How to use OnClick and Draw WKT automatically on Openlayers + React + MySQL?

253 views Asked by At

(1)Copy WKT strings in Blue => (2)Paste in Text Area => (3)Click Draw => (4)WKT Draw on Map

WKT drawn on Map

Objective: (1)Click on WKT strings in Blue => (2)WKT Draw on Map

Current Problem: 1)Copy WKT strings 2)Paste inside textare 3)Click Draw 4)WKT draw on map

Objective: 1)Click on WKT strings 2)WKT draw on map

import './App.css';
import React, {
    useState,
    useEffect
} from 'react';
import OlMap from 'ol/Map';
import LayerGroup from 'ol/layer/Group';
import OlView from 'ol/View';
import OlLayerTile from 'ol/layer/Tile';
import {
    Form,
    Input,
    Button,
    Tag
} from "antd";
import GeoJSON from 'ol/format/GeoJSON';
import {
    fromLonLat,
    toLonLat,
    transform
} from "ol/proj";
import OlFeature from "ol/Feature";
import WKT from "ol/format/WKT";
import OlSourceOsm from 'ol/source/OSM';
import {
    useTabs,
    TabPanel
} from "react-headless-tabs";
import {
    Tile as TileLayer,
    Vector as VectorLayer
} from "ol/layer";
import {
    Drawer
} from 'antd';
import {
    SimpleButton,
    MapComponent,
    NominatimSearch,
    LayerTree
} from '@terrestris/react-geo';
import '@terrestris/react-geo/dist/Field/NominatimSearch/NominatimSearch.less';
import {
    Style,
    Circle as CircleStyle,
    Fill,
    Stroke
} from "ol/style";
import 'ol/ol.css';
import 'antd/dist/antd.min.css';
import axios from 'axios';
import {
    BiMenu
} from 'react-icons/bi';
import './react-geo.css';
import Dropdown from 'react-bootstrap/Dropdown';
import 'bootstrap/dist/css/bootstrap.min.css';
import {
    Vector as VectorSource
} from "ol/source";
import Circle from 'ol/geom/Circle';
import Feature from 'ol/Feature';
import Data from './Wkt';
import "./WktToMap/WktToMap.scss";
import $ from 'jquery';
const {
    TextArea
} = Input;

export const drawWktFeature = (map, wktFeature) => {
    removeLayer(map, "wktLayer");
    const wktFormat = new WKT();
    const geometry = wktFormat.readGeometry(wktFeature, {
        dataProjection: "EPSG:4326",
        featureProjection: "EPSG:3857",
    });

    if (map) {
        const poly = new OlFeature({
            geometry: geometry,
        });

        console.log(poly.getGeometry().getType().includes("Point"));

        const vectorLayer = new VectorLayer({
            title: "WKT Layer",
            source: new VectorSource({
                features: [poly],
            }),
            style: poly.getGeometry().getType().includes("Point") ?
                new Style({
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: "rgba(0, 98, 255, 0.4)"
                        }),
                        stroke: new Stroke({
                            color: "#0000ff",
                            width: 2,
                        }),
                    }),
                }) :
                new Style({
                    fill: new Fill({
                        color: "rgba(0, 98, 255, 0.4)",
                    }),
                    stroke: new Stroke({
                        color: "#0000ff",
                        width: 2,
                    }),
                }),
        });

        vectorLayer.set("name", "wktLayer");

        map.addLayer(vectorLayer);
        const polygonExtent = vectorLayer
            .getSource()
            .getFeatures()[0]
            .getGeometry()
            .getExtent();
        map.getView().fit(polygonExtent, map.getSize());
    }
};

export const validateGeometry = (geometry) => {
    const wktFormat = new WKT();
    try {
        const geom = wktFormat.readGeometry(geometry, {
            dataProjection: "EPSG:4326",
            featureProjection: "EPSG:3857",
        });
        const poly = new OlFeature({
            geometry: geom,
        });

        return poly.getGeometry().getType();
    } catch (error) {
        return null;
    }
};

//remove layer from map by name
export const removeLayer = (map, layerName) => {
    map.getLayers().forEach((layer) => {
        if (layer && layer.get("name") === layerName) {
            map.removeLayer(layer);
        }
    });
};

function WktToMap({
    map
}) {
    const [inputValue, setInputValue] = useState("");
    const [inputError, setInputError] = useState("");

    useEffect(() => {
        return () => {
            if (map) removeLayer(map, "wktLayer");
        };
    }, []);

    const inputValueChangeHandler = (e) => {
        setInputValue(e.target.value);
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        if (map) {
            if (inputValue) {
                const validation = validateGeometry(inputValue);
                if (validation) {
                    drawWktFeature(map, inputValue);
                    setInputError("");
                } else {
                    removeLayer(map, "wktLayer");
                    setInputError("The submitted geometry is not a valid WKT");
                }
            }
        }
    };

    const handleClearMap = () => {
        if (map) {
            removeLayer(map, "wktLayer");
            setInputError("");
            setInputValue("");
        }
    };


    return ( <
        div className = "wkt-to-map" >
        <
        Form layout = "vertical" >
        <
        Form.Item >
        <
        textarea rows = {
            6
        }
        onChange = {
            inputValueChangeHandler
        }
        /> <
        /Form.Item>

        {
            Boolean(inputError) && ( <
                Tag color = "error"
                className = "full-width error-tag" > {
                    inputError
                } <
                /Tag>
            )
        }

        <
        div className = "two-col-btns-wrapper" >
        <
        button htmlType = "submit"
        type = "primary"
        onClick = {
            handleSubmit
        } >
        Draw <
        /button> <
        button htmlType = "button"
        onClick = {
            handleClearMap
        } >
        Clear <
        /button> <
        /div> <
        /Form> <
        /div>
    );
}


const image = new CircleStyle({
    radius: 5,
    fill: null,
    stroke: new Stroke({
        color: 'red',
        width: 1
    }),
});

const styles = {
    'Point': new Style({
        image: image,
    }),
    'LineString': new Style({
        stroke: new Stroke({
            color: 'green',
            width: 1,
        }),
    }),
    'MultiLineString': new Style({
        stroke: new Stroke({
            color: 'green',
            width: 1,
        }),
    }),
    'MultiPoint': new Style({
        image: image,
    }),
    'MultiPolygon': new Style({
        stroke: new Stroke({
            color: 'yellow',
            width: 1,
        }),
        fill: new Fill({
            color: 'rgba(255, 255, 0, 0.1)',
        }),
    }),
    'Polygon': new Style({
        stroke: new Stroke({
            color: 'blue',
            lineDash: [4],
            width: 3,
        }),
        fill: new Fill({
            color: 'rgba(0, 0, 255, 0.1)',
        }),
    }),
    'GeometryCollection': new Style({
        stroke: new Stroke({
            color: 'magenta',
            width: 2,
        }),
        fill: new Fill({
            color: 'magenta',
        }),
        image: new CircleStyle({
            radius: 10,
            fill: null,
            stroke: new Stroke({
                color: 'magenta',
            }),
        }),
    }),
    'Circle': new Style({
        stroke: new Stroke({
            color: 'red',
            width: 2,
        }),
        fill: new Fill({
            color: 'rgba(255,0,0,0.2)',
        }),
    }),
};

const styleFunction = function(feature) {
    return styles[feature.getGeometry().getType()];
};

const vectorSource = new VectorSource({
    features: new GeoJSON({
        dataProjection: 'EPSG:4326',
        featureProjection: 'EPSG:3857',
    }).readFeatures(Data),
});

vectorSource.addFeature(new Feature(new Circle([5e6, 7e6], 1e6)));


const vectorLayer = new VectorLayer({
    className: "WKT",
    source: vectorSource,
    style: styleFunction,
});


const TabSelector = ({
    isActive,
    children,
    onClick,
}) => (React.createElement("button", {
    className: `mr-8 group inline-flex items-center font-medium text-sm leading-5 cursor-pointer whitespace-nowrap ${isActive
  ? 'border-indigo-500 text-indigo-600 focus:outline-none focus:text-indigo-800 focus:border-indigo-700'
  : 'border-transparent text-gray-500 hover:text-gray-600 hover:border-gray-300 focus:text-gray-600 focus:border-gray-300'}`,
    onClick: onClick
}, children));

const layer = new OlLayerTile({
    source: new OlSourceOsm({})
});

const map = new OlMap({
    view: new OlView({
        center: fromLonLat([108.68593, 3.747128]),
        zoom: 6,
    }),
    layers: [layer,
        new LayerGroup({
            visible: false,
            title: 'WKT',
            name: 'WKT',
            className: 'WKT',
            layers: [vectorLayer],
        }),
        new OlLayerTile({
            name: 'Original',
            className: 'Original',
            visible: false,
            source: new OlSourceOsm({
                name: 'Original',
                title: 'Original',
                className: 'Original'
            })
        })
    ]
});

function Draw() {
    const url = 'http://localhost:3000/mysql4/';
    const [post, setPost] = React.useState(null);
    const [inputValue, setInputValue] = useState("");
    const [inputError, setInputError] = useState("");

    React.useEffect(() => {
        axios.get(url).then((response) => {
            setPost(response.data);
            setInputValue(response.data.WKT_STR)
        });
    }, []);

    const inputValueChangeHandler = (e) => {
        setInputValue(e.target.value);
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        if (map) {
            if (inputValue) {
                const validation = validateGeometry(inputValue);
                if (validation) {
                    drawWktFeature(map, inputValue);
                    setInputError("");
                } else {
                    removeLayer(map, "wktLayer");
                    setInputError("The submitted geometry is not a valid WKT");
                }
            }
        }
    };


    if (!post) return null;
    return ( <
        div >
        <
        table className = "table table-bordered table-striped" >
        <
        thead >
        <
        tr >
        <
        th > Strings < /th> <
        /tr> <
        /thead> <
        tbody > {
            post.map((post, index) => ( <
                tr key = {
                    index
                } >
                <
                td > < a href = '#'
                onClick = {
                    handleSubmit
                } > {
                    post.WKT_STR
                } < /a></td >
                <
                /tr>
            ))
        } <
        /tbody> <
        /table> <
        /div>
    )
}




class WKTsql extends React.Component {
    state = {
        CMS_NO: '',
        WKT_STR: '',
        STATUS: '',
        DATE_ADD: '',
        DATE_CLOSE: '',
        USER_ID: '',
        feedbacks: []
    }


    componentDidMount() {
        const url = 'http://localhost:3000/mysql4/'
        axios.get(url).then(response => response.data)
            .then((data) => {
                this.setState({
                    feedbacks: data
                })
                console.log(this.state.feedbacks)
            })
    }

    render() {
        return ( <
            div className = "container" >
            <
            div className = "col-md" >
            <
            table className = "table table-bordered table-striped" >
            <
            thead >
            <
            tr >
            <
            th > Verify < /th> <
            th > Strings < /th> <
            /tr> <
            /thead> <
            tbody > {
                this.state.feedbacks.map((feedbacks, index) => ( <
                    tr key = {
                        index
                    } >
                    <
                    td > < textarea id = "reviewText" > < /textarea></td >
                    <
                    td > < a href = '#' > {
                        feedbacks.WKT_STR
                    }
                    /</a > < /td> <
                    /tr>
                ))
            } <
            /tbody> <
            /table> <
            /div> <
            /div>
        );
    }
}

function App() {
    const [visible, setVisible] = useState(true);
    const toggleDrawer = () => {
        setVisible(!visible);
    }
    const [showLinks, setShowLinks] = useState(true);
    const [selectedTab, setSelectedTab] = useTabs([
        'home',
        'search',
        'feedbacks',
        'draw',
        'autocomplete',
        'reverse',
        'fullsearch',
        'send',
        'overall',
        'top10',
        'reward',
        'layercont',
        'measure',
        'viewinfo',
        'userlayer'
    ]);

    return ( <
        div className = "example-container" >
        <
        div className = "form-container" >
        <
        div className = "Navbar" >
        <
        div className = "leftSide" >
        <
        div className = "links"
        id = {
            showLinks ? "hidden" : ""
        } >
        <
        Dropdown >
        <
        Dropdown.Toggle variant = "light"
        id = "dropdown-basic" >
        <
        a > < TabSelector isActive = {
            selectedTab === 'home'
        }
        onClick = {
            () => setSelectedTab('home')
        } > Home < /TabSelector></a >
        <
        /Dropdown.Toggle> <
        Dropdown.Menu >
        <
        Dropdown.Item href = "#/action-1" > Layer Control < a > < TabSelector isActive = {
            selectedTab === 'layercont'
        }
        onClick = {
            () => setSelectedTab('layercont')
        } > Layer Control < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-2" > Measure < a > < TabSelector isActive = {
            selectedTab === 'measure'
        }
        onClick = {
            () => setSelectedTab('measure')
        } > Measure < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-3" > View Info < a > < TabSelector isActive = {
            selectedTab === 'viewinfo'
        }
        onClick = {
            () => setSelectedTab('viewinfo')
        } > View Info < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-3" > User Layer < a > < TabSelector isActive = {
            selectedTab === 'userlayer'
        }
        onClick = {
            () => setSelectedTab('userlayer')
        } > User Layer < /TabSelector></a > < /Dropdown.Item> <
        /Dropdown.Menu> <
        /Dropdown> <
        Dropdown >
        <
        Dropdown.Toggle variant = "light"
        id = "dropdown-basic" >
        <
        a > < TabSelector isActive = {
            selectedTab === 'search'
        }
        onClick = {
            () => setSelectedTab('search')
        } > Search < /TabSelector></a >
        <
        /Dropdown.Toggle> <
        Dropdown.Menu >
        <
        Dropdown.Item href = "#/action-1" > Full Search < a > < TabSelector isActive = {
            selectedTab === 'fullsearch'
        }
        onClick = {
            () => setSelectedTab('fullsearch')
        } > Full Search < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-2" > Autocomplete < a > < TabSelector isActive = {
            selectedTab === 'autocomplete'
        }
        onClick = {
            () => setSelectedTab('autocomplete')
        } > Autocomplete < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-3" > Reverse Geocoding < a > < TabSelector isActive = {
            selectedTab === 'reverse'
        }
        onClick = {
            () => setSelectedTab('reverse')
        } > Reverse Geocoding < /TabSelector></a > < /Dropdown.Item> <
        /Dropdown.Menu> <
        /Dropdown> <
        Dropdown >
        <
        Dropdown.Toggle variant = "light"
        id = "dropdown-basic" >
        <
        a > < TabSelector isActive = {
            selectedTab === 'feedbacks'
        }
        onClick = {
            () => setSelectedTab('feedbacks')
        } > Feedbacks < /TabSelector></a >
        <
        /Dropdown.Toggle> <
        Dropdown.Menu >
        <
        Dropdown.Item href = "#/action-1" > Send Feedbacks < a > < TabSelector isActive = {
            selectedTab === 'send'
        }
        onClick = {
            () => setSelectedTab('send')
        } > Send Feedbacks < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-2" > Overall < a > < TabSelector isActive = {
            selectedTab === 'overall'
        }
        onClick = {
            () => setSelectedTab('overall')
        } > Overall < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-3" > Top 10 < a > < TabSelector isActive = {
            selectedTab === 'top10'
        }
        onClick = {
            () => setSelectedTab('top10')
        } > Top 10 < /TabSelector></a > < /Dropdown.Item> <
        Dropdown.Item href = "#/action-3" > Reward < a > < TabSelector isActive = {
            selectedTab === 'reward'
        }
        onClick = {
            () => setSelectedTab('reward')
        } > Reward < /TabSelector></a > < /Dropdown.Item> <
        /Dropdown.Menu> <
        /Dropdown> <
        Dropdown >
        <
        Dropdown.Toggle variant = "light"
        id = "dropdown-basic" >
        <
        a > < TabSelector isActive = {
            selectedTab === 'draw'
        }
        onClick = {
            () => setSelectedTab('draw')
        } > Draw < /TabSelector></a >
        <
        /Dropdown.Toggle> <
        Dropdown.Menu >
        <
        Dropdown.Item href = "#/action-1" > Action1 < /Dropdown.Item> <
        Dropdown.Item href = "#/action-2" > Action2 < /Dropdown.Item> <
        Dropdown.Item href = "#/action-3" > Action3 < /Dropdown.Item> <
        /Dropdown.Menu> <
        /Dropdown> <
        /div> <
        button className = "menu"
        onClick = {
            () => setShowLinks(!showLinks)
        } > < BiMenu / > < /button> <
        /div> <
        /div> <
        /div> <
        MapComponent map = {
            map
        }
        /> <
        SimpleButton style = {
            {
                position: 'fixed',
                top: '20px',
                right: '30px'
            }
        }
        onClick = {
            toggleDrawer
        }
        iconName = "bars" / >
        <
        Drawer title = "Geomatics Solution"
        placement = "right"
        onClose = {
            toggleDrawer
        }
        visible = {
            visible
        }
        mask = {
            false
        } >
        <
        div className = "p-4" >
        <
        TabPanel hidden = {
            selectedTab !== 'home'
        } > Home < h1 > Welcome to Smartmap API < /h1></TabPanel >
        <
        TabPanel hidden = {
            selectedTab !== 'search'
        } > Search < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'feedbacks'
        } > Feedbacks < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'fullsearch'
        } > Full Search < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'reverse'
        } > Reverse Geocoding < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'autocomplete'
        } > Autocomplete < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'send'
        } > Send Feedbacks < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'overall'
        } > Overall < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'top10'
        } > Top 10 < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'reward'
        } > Reward < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'layercont'
        } > Layer Control < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'measure'
        } > Measure < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'viewinfo'
        } > View Info < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'userlayer'
        } > User Layer < /TabPanel> <
        TabPanel hidden = {
            selectedTab !== 'draw'
        } > Draw < Draw / > < /TabPanel> <
        /div> <
        /Drawer> <
        /div>
    );
}

export default App;

Thank you very much.

0

There are 0 answers