Redone OLM

This commit is contained in:
lokeshramchand-ctrl 2025-06-05 22:36:43 +05:30
parent 8e13e2ec6a
commit 44c5d2e831
6 changed files with 255 additions and 290 deletions

40
package-lock.json generated
View file

@ -17,6 +17,7 @@
},
"devDependencies": {
"@eslint/js": "^9.21.0",
"@types/ol": "^6.5.3",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",
@ -1219,6 +1220,13 @@
"win32"
]
},
"node_modules/@types/arcgis-rest-api": {
"version": "10.4.8",
"resolved": "https://registry.npmjs.org/@types/arcgis-rest-api/-/arcgis-rest-api-10.4.8.tgz",
"integrity": "sha512-MapiW0nP/5X0BUHmtRNEjbK0xrxS6n0syZWQk25H4ObFFwuK1+pGl7LQfOLgpsVM849WQ1b2sKIvWqEAvPwzCA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@ -1270,12 +1278,32 @@
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="
},
"node_modules/@types/geojson": {
"version": "7946.0.16",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"devOptional": true
},
"node_modules/@types/ol": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/@types/ol/-/ol-6.5.3.tgz",
"integrity": "sha512-C0Sm5dytTfRxztYFMuWq0IBJYfMffPF4GzXI/s4ZyJlNZ8AAdS+9fW0iGOyYkTb3ZQmfYWYdAzMqwGXfHVw+3A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/arcgis-rest-api": "*",
"@types/geojson": "*",
"@types/rbush": "*",
"@types/topojson-specification": "*"
}
},
"node_modules/@types/rbush": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-4.0.0.tgz",
@ -1299,6 +1327,16 @@
"@types/react": "^19.0.0"
}
},
"node_modules/@types/topojson-specification": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/topojson-specification/-/topojson-specification-1.0.5.tgz",
"integrity": "sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.29.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz",
@ -2512,6 +2550,7 @@
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/ol/-/ol-10.5.0.tgz",
"integrity": "sha512-nHFx8gkGmvYImsa7iKkwUnZidd5gn1XbMZd9GNOorvm9orjW9gQvT3Naw/MjIasVJ3cB9EJUdCGR2EFAulMHsQ==",
"license": "BSD-2-Clause",
"dependencies": {
"@types/rbush": "4.0.0",
"earcut": "^3.0.0",
@ -2528,6 +2567,7 @@
"version": "4.0.31",
"resolved": "https://registry.npmjs.org/ol-ext/-/ol-ext-4.0.31.tgz",
"integrity": "sha512-byh26JcXZggkLUY79+c29cxf2ovkkwz5niWJzOIN+dLPDJ+ogSn0y4Wl8fIS9O2JtQff5/cInHRImgZBvl+N1g==",
"license": "BSD-3-Clause",
"peerDependencies": {
"ol": ">= 5.3.0"
}

View file

@ -19,6 +19,7 @@
},
"devDependencies": {
"@eslint/js": "^9.21.0",
"@types/ol": "^6.5.3",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",

View file

@ -1,11 +1,11 @@
//import { useState, useEffect } from 'react'
import { useState, useEffect } from 'react'
async function getBills(data) {
const bill_ids: number[] = [];
const bill_titles: string[] = [];
var results: any = data["searchresult"]["results"];
for(var i = 0; i < data["searchresult"]["summary"]["count"]; i++){
var bill_id: integer = results[i]["bill_id"];
var bill_id: number = results[i]["bill_id"];
bill_ids.push(bill_id);
}
for(var i = 0; i < bill_ids.length; i++){

View file

@ -1,17 +1,17 @@
import {useRef} from 'react';
import { useRef } from 'react';
import Map from 'ol/Map';
import View from 'ol/View';
import EsriJSON from 'ol/format/EsriJSON';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import {tile as tileStrategy} from 'ol/loadingstrategy';
import {fromLonLat} from 'ol/proj';
import { tile as tileStrategy } from 'ol/loadingstrategy';
import { fromLonLat } from 'ol/proj';
import ImageTile from 'ol/source/ImageTile';
import VectorSource from 'ol/source/Vector';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import Style from 'ol/style/Style';
import {createXYZ} from 'ol/tilegrid';
import { createXYZ } from 'ol/tilegrid';
const serviceUrl =
'https://services-eu1.arcgis.com/NPIbx47lsIiu2pqz/ArcGIS/rest/services/' +
@ -44,8 +44,8 @@ const style = new Style({
const OpenLayerEsri = () => {
const mapDivRef = useRef<HTMLDivElement>(null);
const vectorSource = new VectorSource({
const mapDivRef = useRef<HTMLDivElement>(null);
const vectorSource = new VectorSource({
format: new EsriJSON(),
url: function (extent, projection) {
// ArcGIS Server only wants the numeric portion of the projection ID.
@ -89,9 +89,9 @@ const vectorSource = new VectorSource({
'University of Leicester (commissioned by the ' +
'<a href="https://www.arcgis.com/home/item.html?id=' +
'd5f05b1dc3dd4d76906c421bc1727805">National Trust</a>)',
});
});
const vector = new VectorLayer({
const vector = new VectorLayer({
source: vectorSource,
style: function (feature) {
const classify = feature.get('LU_2014');
@ -100,9 +100,9 @@ const vector = new VectorLayer({
return style;
},
opacity: 0.7,
});
});
const raster = new TileLayer({
const raster = new TileLayer({
source: new ImageTile({
attributions:
'Tiles © <a href="https://services.arcgisonline.com/ArcGIS/' +
@ -111,16 +111,16 @@ const raster = new TileLayer({
'https://server.arcgisonline.com/ArcGIS/rest/services/' +
'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
}),
});
});
const map = new Map({
layers: [raster,vector],
const map = new Map({
layers: [raster, vector],
target: mapDivRef.current as HTMLDivElement,
view: new View({
center: fromLonLat([1.72, 52.4]),
zoom: 14,
}),
});
});
return (

View file

@ -1,135 +1,53 @@
import { useEffect, useRef, useState } from 'react';
import { Map, View } from 'ol';
import 'ol/ol.css';
import TileLayer from 'ol/layer/Tile';
import Overlay from 'ol/Overlay'
//import Popup from 'ol/Popup'
//import {tile as tileStrategy} from 'ol/loadingstrategy';
//import {createXYZ} from 'ol/tilegrid';
//import {Search} from 'ol-ext/control/SearchFeature';
import { OSM } from 'ol/source';
import {fromLonLat} from 'ol/proj';
//import {Select} from 'ol/interaction/Select';
import { fromLonLat } from 'ol/proj';
import { Coordinate } from 'ol/coordinate';
import VectorLayer from "ol/layer/Vector"
import VectorSource from "ol/source/Vector"
import GeoJSON from "ol/format/GeoJSON"
//import EsriJSON from "ol/format/EsriJSON"
import {Style, Icon, Fill, Circle, Stroke} from "ol/style"
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import Style from 'ol/style/Style';
import Stroke from 'ol/style/Stroke';
import Fill from 'ol/style/Fill';
const OpenLayersMap = () => {
const [term, setTerm] = useState({});
// const [term, setTerm] = useState({});
const [term, setTerm] = useState<string>('');
const [address, setAddress] = useState();
//Submit Button Logic
const submitForm = async (event: React.FormEvent<HTMLFormElement>) => {
// Preventing the page from reloading
event.preventDefault();
//fetch(`https://nominatim.openstreetmap.org/search?q=${term}&format=json&polygon=1&addressdetails=1`)
// .then(response => response.json())
//.then(response => console.log(response))
// .then(({data: address}) => {setAddress(address)})
//console.log(address)
const response = await fetch(`https://nominatim.openstreetmap.org/search?q=${term}&format=json&polygon=1&addressdetails=1`)
const json = await response.json();
console.log(json);
setAddress(json);
console.log(address);
// Do something
alert(term);
}
const [data,setData] = useState({});
//Submit Button Logic
//const [data, setData] = useState({});
const mapDivRef = useRef<HTMLDivElement>(null);
const popupRef = useRef<HTMLDivElement>(null);
const [clickedCoordinate, setClickedCoordinate] = useState<Coordinate>();
const mapRef = useRef<Map | null>(null);
const url_1: any = "https://geo.sandag.org/server/rest/services/Hosted/Address_Points/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&resultType=standard&f=geojson";
const url_2: any = "https://geo.sandag.org/server/rest/services/Hosted/Parcels/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&resultType=none&f=geojson";
const url_3: any = "https://geo.sandag.org/server/rest/services/Hosted/Zoning_Base_SD/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&resultType=standard&f=geojson";
const url_4: any = "https://geo.sandag.org/server/rest/services/Hosted/Water_Main_SD/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&resultType=standard&f=geojson";
const vectorLayer: any = new VectorLayer({
source: new VectorSource({
format: new GeoJSON(),
url: url_2,
style: new Style({
fill: new Fill({
color: 'red',
}),
stroke: new Stroke({
color: 'black',
width: 2.25
}),
}),
}),
});
const vectorsource_offset: any = new VectorSource();
const vectorsource_offset_1: any = new VectorSource();
const format: any = new GeoJSON();
//vectorsource_offset.addFeature(format.readFeatures(data))
const vectorLayer2: any = new VectorLayer({
source: vectorsource_offset,
});
const vectorLayer1: any = new VectorLayer({
source: new VectorSource({
format: new GeoJSON(),
url: url_1,
attributions: ['Los Angeles GeoHub |']
}),
});
const vectorLayer_given: any = new VectorLayer();
const vectorLayer_parcel: any = new VectorLayer();
// default view
const vecLayerCreation = async (url,length,map,vectorLayer) => {
const vectorsource_layer: any = new VectorSource();
const format: any = new GeoJSON();
const urls: string[] = [];
for(var i = 0; i < length; i = i + 2000){
urls.push(url + `&resultOffset=${i}`);
}
console.log(urls)
urls.forEach((url_each,index) => {
fetch(url_each)
.then(response => response.json())
.then(response => vectorsource_layer.addFeatures(format.readFeatures(response, {
dataProjection: 'EPSG:4326',
featureProjection: map.getView().getProjection(),
})))
.catch(error => console.error(error));
})
//vectorsource_offset.addFeature(format.readFeatures(data))
vectorLayer.setSource(vectorsource_layer)
console.log(vectorLayer)
}
useEffect(() => {
var ar = [-117.9112790,34.0296349]
//Initial Location
var ar = [-117.9112790, 34.0296349]
var proj_lat_long = fromLonLat(ar);
const overlay = new Overlay({
element: popupRef.current as HTMLDivElement,
autoPan: {
animation: {
duration: 250,
},
},
})
//Map Display
const map = new Map({
target: mapDivRef.current as HTMLDivElement,
layers: [
@ -137,99 +55,103 @@ const overlay = new Overlay({
source: new OSM(),
}),
],
view: new View({
//End of Map Initialization
view: new View({
center: [-13042228, 3857849],
//center: proj_lat_long,
zoom: 12,
}),
overlays: [overlay],
});
//vecLayerCreation(url_4,3718,map,vectorLayer_given)
//vecLayerCreation(url_2,1088001,map,vectorLayer_parcel)
//map.addLayer(vectorLayer_given)
//const true_we = map.setLayers([vectorLayer_parcel])
//console.log(true_we)
mapRef.current = map;
map.on('click', (e) => {
setClickedCoordinate(e.coordinate);
// Get Coordinates of click
// Get Coordinates of click
const coordinate = e.coordinate;
//const hdms = toStringHDMS(toLonLat(coordinate));
const feature = map.forEachFeatureAtPixel(e.pixel, function (feature) {
const feature = map.forEachFeatureAtPixel(e.pixel, function (feature) {
return feature;
});
// Show popup at clicked position
overlay.setPosition(coordinate);
if(feature)
console.log("feature " + JSON.stringify(feature,null,'\t'));
if(feature && feature.get("subname")){
if (popupRef.current) {
popupRef.current.innerHTML = `<p>Parcel</p><code>` +
`<p>Parcel ID ${feature.get('parcelid')}</p>` +
`<p>APN ${feature.get('apn')}</p>` +
`<p>Legldesc ${feature.get('legldesc')}</p>` +
`<p>x \& y coord${feature.get('x_coord')} / ${feature.get('y_coord')}</p>` +
`<p>${feature.get('situs_address')} ${feature.get('situs_street')} ${feature.get('situs_suffix')} ${feature.get('situs_community')} ${feature.get('situs_zip')}</p>` +
`<p> Unit Qty ${feature.get('unitqty')}</p>` +
`<p> Usable sq ft. ${feature.get('usable_sq_feet')}</p>` +
`<p> total lvg area ${feature.get('total_lvg_area')}</p>` +
`<p>bedrooms ${feature.get('bedrooms')} Baths ${feature.get('baths')}</p>` +
`</code>`;
}
}
else if(feature && feature.get('addrsfx')){
if (popupRef.current) {
popupRef.current.innerHTML = `<p>You clicked here:</p><code>` +
`<p>Address Point</p>` +
`<p>${feature.get('addrname')} ${feature.get('addrsfx')}</p>` +
`<p>${feature.get('addrzip')}</p>` +
`<p>${feature.get('community')}</p>` +
`</code>`;
}
}
else{
if (popupmef.current) {
popupRef.current.innerHTML = `<p>You clicked here:</p><code>` +
`<p>Not a parcel or Address Point</p>` +
`</code>`;
}
}
overlay.setPosition(coordinate)
});
// Converting lat long to mercator projection
//Needed for Searching Location
// Zoom to lat lon
if(address){
console.log("asdf" + address[0].lat)
if (address) {
console.log("ASDF" + address[1].lat)
var ar = [address[0].lat, address[0].lon]
var ar = [address[1].lon, address[1].lat]
var proj_lat_long = fromLonLat(ar);
map.setView(
new View({
center: proj_lat_long,
zoom: 17
zoom: 15
})
)
}
// fit view to geometry of geojson feature with padding
//def_view.fit(geoJSONFeatures[0].getGeometry().getExtent(), { padding: [100, 100, 100, 100]});
return () => map.setTarget(undefined);
}, [address]);
//Parcel Layer
useEffect(() => {
if (!mapRef.current) return;
const url = 'https://geo.sandag.org/server/rest/services/Hosted/Parcels/FeatureServer/0/query' +
'?where=1=1&outFields=*&returnGeometry=true&f=geojson&resultRecordCount=5000';
fetch(url)
.then((res) => res.json())
.then((geojsonData) => {
const vectorSource = new VectorSource({
features: new GeoJSON().readFeatures(geojsonData, {
featureProjection: 'EPSG:3857', // Make sure features match OSM projection
}),
});
const vectorLayer = new VectorLayer({
source: vectorSource,
style: new Style({
stroke: new Stroke({
color: 'green',
width: 1.5,
}),
fill: new Fill({
color: 'rgba(0, 255, 0, 0.1)',
}),
}),
});
mapRef.current?.addLayer(vectorLayer);
// ✅ Fit map to features
mapRef.current?.getView().fit(vectorSource.getExtent(), {
padding: [20, 20, 20, 20],
maxZoom: 17,
});
})
.catch((err) => {
console.error('Error loading GeoJSON:', err);
});
}, []);
//UI Downstairs
return (
<>
<div ref={mapDivRef} className='map'>
@ -245,7 +167,6 @@ var ar = [address[0].lat, address[0].lon]
<button type="submit" className="btn">Submit</button>
</form>
</div>
<div ref={popupRef} className="ol-popup"/>
</div>
{clickedCoordinate && (
<span className='coordinates-container'>
@ -257,3 +178,6 @@ var ar = [address[0].lat, address[0].lon]
};
export default OpenLayersMap;

View file

@ -14,7 +14,7 @@ const SearchBar = () => {
console.log("print");
fetch(`https://nominatim.openstreetmap.org/search?q=${term}&format=json&polygon=1&addressdetails=1`)
.then(response => response.json())
.then(respone => console.log("printed address: " + response))
.then(response => console.log("printed address: " + response))
}
useEffect(() => {
@ -34,7 +34,7 @@ const SearchBar = () => {
placeholder="Enter a term"
className="input"
/>
<button type="submit" className="btn">Submi/button>
<button type="submit" className="btn">Submit</button>
</form>
</div>
);