Add MN Ambulance Service Areas layer
Requested-By: Isaac Swift
This commit is contained in:
parent
e233c8dda6
commit
66205965ce
4 changed files with 115 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ import survey_markers from './survey-markers/index.js';
|
||||||
import tjx from './tjx/index.js';
|
import tjx from './tjx/index.js';
|
||||||
import minnesotaAdventureTrails from './minnesota-adventure-trails/index.js';
|
import minnesotaAdventureTrails from './minnesota-adventure-trails/index.js';
|
||||||
import cropHistory from './crop-history/index.js';
|
import cropHistory from './crop-history/index.js';
|
||||||
|
import mnAmbulanceServiceAreas from './mn-ambulance-service-areas/layer.js';
|
||||||
|
|
||||||
const layerCategories = [
|
const layerCategories = [
|
||||||
{ // Base maps
|
{ // Base maps
|
||||||
|
|
@ -90,6 +91,7 @@ const layerCategories = [
|
||||||
name: "Bikepacking.com Routes",
|
name: "Bikepacking.com Routes",
|
||||||
layer: bikepackingLayer,
|
layer: bikepackingLayer,
|
||||||
},
|
},
|
||||||
|
mnAmbulanceServiceAreas,
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
minnesotaAdventureTrails,
|
minnesotaAdventureTrails,
|
||||||
|
|
|
||||||
3
layers/mn-ambulance-service-areas/README.md
Normal file
3
layers/mn-ambulance-service-areas/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
https://mn.gov/oems/ambulance-services/primary-service-area-maps.jsp
|
||||||
|
|
||||||
|
https://experience.arcgis.com/experience/a222fe7ceaf44f868ec3c0f5dafe8446/page/Page
|
||||||
56
layers/mn-ambulance-service-areas/get_data.py
Executable file
56
layers/mn-ambulance-service-areas/get_data.py
Executable file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i python3 -p python3 python3Packages.requests python3Packages.shapely
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from collections import defaultdict
|
||||||
|
from shapely.geometry import shape, mapping
|
||||||
|
from shapely.ops import unary_union
|
||||||
|
|
||||||
|
# https://services.arcgis.com/9OIuDHbyhmH91RfZ/arcgis/rest/services/EMSRB_Statewide/FeatureServer/0/query?f=pbf&cacheHint=true&maxRecordCountFactor=4&resultOffset=0&resultRecordCount=8000&where=1%3D1&orderByFields=OBJECTID%20ASC&outFields=AmbServNam%2CCounty%2COBJECTID&outSR=102100&spatialRel=esriSpatialRelIntersects
|
||||||
|
|
||||||
|
url = "https://services.arcgis.com/9OIuDHbyhmH91RfZ/arcgis/rest/services/EMSRB_Statewide/FeatureServer/0/query"
|
||||||
|
params = {
|
||||||
|
"f": "geojson",
|
||||||
|
"cacheHint": "true",
|
||||||
|
"maxRecordCountFactor": "4",
|
||||||
|
"resultOffset": "0",
|
||||||
|
"resultRecordCount": "8000",
|
||||||
|
"where": "1=1",
|
||||||
|
"outFields": "AmbServNam,County",
|
||||||
|
"outSR": "102100",
|
||||||
|
"spatialRel": "esriSpatialRelIntersects",
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.get(url, params=params)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
data = json.loads(response.text)
|
||||||
|
|
||||||
|
services = defaultdict(list)
|
||||||
|
|
||||||
|
for feature in data["features"]:
|
||||||
|
service_name = feature["properties"].get("AmbServNam", "Unknown")
|
||||||
|
services[service_name].append(feature)
|
||||||
|
|
||||||
|
merged_features = []
|
||||||
|
|
||||||
|
for service_name, features in services.items():
|
||||||
|
merged_features.append(
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {
|
||||||
|
"AmbServNam": service_name,
|
||||||
|
},
|
||||||
|
"geometry": mapping(unary_union([shape(feature["geometry"]) for feature in features])),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
merged_data = {
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"crs": {"type": "name", "properties": {"name": "EPSG:3857"}},
|
||||||
|
"features": merged_features,
|
||||||
|
}
|
||||||
|
|
||||||
|
with open("mn-ambulance-service-areas.geojson", "w", encoding="utf-8") as f:
|
||||||
|
json.dump(merged_data, f)
|
||||||
54
layers/mn-ambulance-service-areas/layer.js
Normal file
54
layers/mn-ambulance-service-areas/layer.js
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import GeoJSON from 'ol/format/GeoJSON.js';
|
||||||
|
import VectorLayer from 'ol/layer/Vector.js';
|
||||||
|
import VectorSource from 'ol/source/Vector.js';
|
||||||
|
|
||||||
|
import serviceAreas from './mn-ambulance-service-areas.geojson?url';
|
||||||
|
|
||||||
|
import { Fill, Stroke, Style, Text } from 'ol/style.js';
|
||||||
|
|
||||||
|
window.chosenColors = {};
|
||||||
|
window.chosenColors2 = {};
|
||||||
|
|
||||||
|
function style(feature){
|
||||||
|
const name = feature.get('AmbServNam');
|
||||||
|
// // djb2 -- results in very non-uniform distribution
|
||||||
|
// // https://web.archive.org/web/20251011200517/https://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
// let hash = 5381;
|
||||||
|
// for (let i = 0; i < name.length; i++) {
|
||||||
|
// hash = hash * 33 + name.charCodeAt(i);
|
||||||
|
// }
|
||||||
|
// const colorDeg = hash % 360;
|
||||||
|
|
||||||
|
// erichash -- thanks @villnoweric
|
||||||
|
let hash = 0;
|
||||||
|
for (let i = 0; i < name.length; i++) {
|
||||||
|
hash += name.charCodeAt(i);
|
||||||
|
}
|
||||||
|
let colorDeg = hash % 360;
|
||||||
|
|
||||||
|
return new Style({
|
||||||
|
text: new Text({
|
||||||
|
text: name,
|
||||||
|
}),
|
||||||
|
fill: new Fill({
|
||||||
|
color: `lch(50% 50 ${colorDeg} / 40%)`,
|
||||||
|
}),
|
||||||
|
stroke: new Stroke({
|
||||||
|
color: `lch(50% 50 ${colorDeg})`,
|
||||||
|
width: 1.25,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const layer = {
|
||||||
|
name: "MN Ambulance Service Areas",
|
||||||
|
layer: new VectorLayer({
|
||||||
|
source: new VectorSource({
|
||||||
|
url: serviceAreas,
|
||||||
|
format: new GeoJSON(),
|
||||||
|
}),
|
||||||
|
style: style,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
export default layer;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue