docker file and parcel

This commit is contained in:
priyatham 2025-04-14 02:03:16 -07:00
parent ffdab5ce24
commit 54e70beb0e
9 changed files with 565 additions and 245 deletions

13
Dockerfile Normal file
View file

@ -0,0 +1,13 @@
FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 5173
CMD [ "npm", "run", "dev"]

448
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
@ -13,7 +13,8 @@
"ol": "^10.5.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.5.0"
"react-router-dom": "^7.5.0",
"vite-plugin-checker": "^0.9.1"
},
"devDependencies": {
"@eslint/js": "^9.21.0",

View file

@ -15,5 +15,17 @@
.coordinates-container {
position: absolute;
bottom: 0;
bottom: -2px;
}
.ol-popup{
position: absolute;
background-color: white;
padding: 5px;
border-radius: 5px;
border: 1px solid black;
transform: translate(-50%, -100%);
pointer-events: none;
width: 220px;
color: black;
};

View file

@ -1,6 +1,7 @@
import { useState } from 'react'
import './App.css'
import OpenLayerMap from './components/OpenLayerMap';
import OpenLayerEsri from './components/OpenLayerEsri';
import LegiScanAPI from './components/LegiScanAPI';
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
@ -11,8 +12,9 @@ function App() {
return (
<Router>
<Routes>
<Route exact path="/" element={<OpenLayerMap />} />
<Route exact path="/legi" element={<LegiScanAPI />} />
<Route path="/" element={<OpenLayerMap />} />
<Route path="/esri" element={<OpenLayerEsri />} />
<Route path="/legi" element={<LegiScanAPI />} />
</Routes>
</Router>
);

View file

@ -1,4 +1,4 @@
import { useState, useEffect } from 'react'
//import { useState, useEffect } from 'react'
async function getBills(data) {
const bill_ids: number[] = [];

View file

@ -0,0 +1,131 @@
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 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';
const serviceUrl =
'https://services-eu1.arcgis.com/NPIbx47lsIiu2pqz/ArcGIS/rest/services/' +
'Neptune_Coastline_Campaign_Open_Data_Land_Use_2014/FeatureServer/';
const layer = '0';
const fillColors = {
'Lost To Sea Since 1965': [0, 0, 0, 1],
'Urban/Built-up': [104, 104, 104, 1],
'Shacks': [115, 76, 0, 1],
'Industry': [230, 0, 0, 1],
'Wasteland': [230, 0, 0, 1],
'Caravans': [0, 112, 255, 0.5],
'Defence': [230, 152, 0, 0.5],
'Transport': [230, 152, 0, 1],
'Open Countryside': [255, 255, 115, 1],
'Woodland': [38, 115, 0, 1],
'Managed Recreation/Sport': [85, 255, 0, 1],
'Amenity Water': [0, 112, 255, 1],
'Inland Water': [0, 38, 115, 1],
};
const style = new Style({
fill: new Fill(),
stroke: new Stroke({
color: [0, 0, 0, 1],
width: 0.5,
}),
});
const OpenLayerEsri = () => {
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.
const srid = projection
.getCode()
.split(/:(?=\d+$)/)
.pop();
const url =
serviceUrl +
layer +
'/query/?f=json&' +
'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' +
encodeURIComponent(
'{"xmin":' +
extent[0] +
',"ymin":' +
extent[1] +
',"xmax":' +
extent[2] +
',"ymax":' +
extent[3] +
',"spatialReference":{"wkid":' +
srid +
'}}',
) +
'&geometryType=esriGeometryEnvelope&inSR=' +
srid +
'&outFields=*' +
'&outSR=' +
srid;
return url;
},
strategy: tileStrategy(
createXYZ({
tileSize: 512,
}),
),
attributions:
'University of Leicester (commissioned by the ' +
'<a href="https://www.arcgis.com/home/item.html?id=' +
'd5f05b1dc3dd4d76906c421bc1727805">National Trust</a>)',
});
const vector = new VectorLayer({
source: vectorSource,
style: function (feature) {
const classify = feature.get('LU_2014');
const color = fillColors[classify] || [0, 0, 0, 0];
style.getFill().setColor(color);
return style;
},
opacity: 0.7,
});
const raster = new TileLayer({
source: new ImageTile({
attributions:
'Tiles © <a href="https://services.arcgisonline.com/ArcGIS/' +
'rest/services/World_Topo_Map/MapServer">ArcGIS</a>',
url:
'https://server.arcgisonline.com/ArcGIS/rest/services/' +
'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
}),
});
const map = new Map({
layers: [raster,vector],
target: mapDivRef.current as HTMLDivElement,
view: new View({
center: fromLonLat([1.72, 52.4]),
zoom: 14,
}),
});
return (
<>
<div ref={mapDivRef} className='map' />
</>
);
}
export default OpenLayerEsri

View file

@ -3,129 +3,132 @@ import { Map, View } from 'ol';
import 'ol/ol.css';
import TileLayer from 'ol/layer/Tile';
import {tile as tileStrategy} from 'ol/loadingstrategy';
import {createXYZ} from 'ol/tilegrid';
import Overlay from 'ol/Overlay'
//import Popup from 'ol/Popup'
//import {tile as tileStrategy} from 'ol/loadingstrategy';
//import {createXYZ} from 'ol/tilegrid';
import { OSM } from 'ol/source';
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} from "ol/style"
import {getCenter} from 'ol/extent';
import ImageLayer from 'ol/layer/Image';
import ImageArcGISRest from 'ol/source/ImageArcGISRest';
//import EsriJSON from "ol/format/EsriJSON"
import {Style, Icon, Fill, Circle, Stroke} from "ol/style"
const OpenLayersMap = () => {
const mapDivRef = useRef<HTMLDivElement>(null);
const [olMap, setOlMap] = useState<Map>();
const popupRef = useRef<HTMLDivElement>(null);
const [clickedCoordinate, setClickedCoordinate] = useState<Coordinate>();
const mapRef = useRef()
// // read geojson feature
// const geoJSONFeatures: any = new GeoJSON().readFeatures(../assets/Address_Points.geojson)
// // create vector source
// const vectorSource: any = new VectorSource({
// features: geoJSONFeatures,
// })
// // create vector layer with source
// const vectorLayer :any = new VectorLayer({
// source: vectorSource,
// })
const url: any =
'https://sampleserver6.arcgisonline.com/ArcGIS/rest/services/' +
'USA/MapServer';
const url_1: any = "https://geo.sandag.org/server/rest/services/Hosted/Address_Points/FeatureServer/";
const layer: any = '0';
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 vectorLayer: any = new VectorLayer({
source: new VectorSource({
format: new GeoJSON(),
url: './assets/Address_Points.geojson'
url: url_2,
style: new Style({
fill: new Fill({
color: 'red',
}),
stroke: new Stroke({
color: 'black',
width: 2.25
}),
}),
}),
});
const vectorLayer1: any = new VectorLayer({
source: new VectorSource({
format: new GeoJSON(),
url: url_1,
attributions: ['Los Angeles GeoHub |']
}),
});
const vectorSource: any = new VectorSource({
format: new EsriJSON(),
url: function (extent, resolution, projection) {
// ArcGIS Server only wants the numeric portion of the projection ID.
const srid: any = projection.getCode().split(/:(?=\d+$)/).pop();
const url =
url_1 +
layer +
'/query/?f=json&' +
'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' +
encodeURIComponent(
'{"xmin":' +
extent[0] +
',"ymin":' +
extent[1] +
',"xmax":' +
extent[2] +
',"ymax":' +
extent[3] +
',"spatialReference":{"wkid":' +
srid +
'}}',
) +
'&geometryType=esriGeometryEnvelope&inSR=' +
srid +
'&outFields=*' +
'&outSR=' +
srid;
return url;
},
strategy: tileStrategy(
createXYZ({
tileSize: 512,
}),
),
attributions:
'University of Leicester (commissioned by the ' +
'<a href="https://www.arcgis.com/home/item.html?id=' +
'd5f05b1dc3dd4d76906c421bc1727805">National Trust</a>)',
});
// default view
const def_view: any = new View({
center: [0, 0],
zoom: 2,
})
useEffect(() => {
const overlay = new Overlay({
element: popupRef.current as HTMLDivElement,
autoPan: {
animation: {
duration: 250,
},
},
})
const map = new Map({
target: mapDivRef.current as HTMLDivElement,
layers: [
new TileLayer({
source: new OSM(),
}),
new ImageLayer({
source: new ImageArcGISRest({
ratio: 1,
params: {},
url: './assets/Address_Points.geojson',
}),
}),
vectorLayer,
vectorLayer1
],
view: new View({
center: [-10997148, 4569099],
zoom: 4,
})
center: [-13042228, 3857849],
zoom: 12,
}),
overlays: [overlay],
});
map.on('click', (e) => {
setClickedCoordinate(e.coordinate);
// Get Coordinates of click
const coordinate = e.coordinate;
//const hdms = toStringHDMS(toLonLat(coordinate));
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));
if(feature && feature.get("subname")){
if (popupRef.current) {
popupRef.current.innerHTML = `<p>You clicked here:</p><code>` +
`<p>Parcel</p>` +
`<p>${feature.get('subname')}</p>` +
`<p> Unit Qty ${feature.get('unitqty')}</p>` +
`<p>${feature.get('situs_community')} ${feature.get('situs_zip')}</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 (popupRef.current) {
popupRef.current.innerHTML = `<p>You clicked here:</p><code>` +
`<p>Not a parcel or Address Point</p>` +
`</code>`;
}
}
overlay.setPosition(coordinate)
});
setOlMap(map);
// fit view to geometry of geojson feature with padding
//def_view.fit(geoJSONFeatures[0].getGeometry().getExtent(), { padding: [100, 100, 100, 100]});
@ -135,13 +138,13 @@ view: new View({
return (
<>
<div ref={mapDivRef} className='map' />
<div ref={mapDivRef} className='map'>
<div ref={popupRef} className="ol-popup"/>
</div>
{clickedCoordinate && (
<span className='coordinates-container'>
You clicked at: {clickedCoordinate[0]} /{' '}
{clickedCoordinate[1]}
You clicked at: {clickedCoordinate[0]} /{' '} {clickedCoordinate[1]}
</span>
)}
</>
);

View file

@ -1,7 +1,13 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import checker from 'vite-plugin-checker';
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [checker({typescript: false}),react()],
server: {
allowedHosts: true,
host:true,
origin: 'http://localhost:5173',
},
})