diff --git a/layers/index.js b/layers/index.js index 31d45dd..149de36 100644 --- a/layers/index.js +++ b/layers/index.js @@ -4,6 +4,7 @@ import Stamen from 'ol/source/Stamen.js'; import amtrakLayer from './amtrak/layer.js'; import arenasLayer from './nhl-arenas/layer.js'; +import menardsLayer from './menards/layer.js'; const layerCategories = [ { @@ -56,6 +57,10 @@ const layerCategories = [ name: "NHL Arenas", layer: arenasLayer, }, + { + name: "Menards", + layer: menardsLayer, + }, ] } ]; diff --git a/layers/menards/get_data.py b/layers/menards/get_data.py new file mode 100755 index 0000000..7b7f08e --- /dev/null +++ b/layers/menards/get_data.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import requests +import re +import json + +# Stolen from my machine, appears to work; sufficient and necessary to get +# around their firewall apparently? Last time this didn't work, so I wonder if +# their protections get stronger as I make more requests. Hopefully not! +UA={ + "User-Agent": 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/114.0' +} + +res = requests.get('https://www.menards.com/store-details/locator.html', headers=UA) + +content = res.text + +# # For debugging, only fetch the above once; then cache it: +# with open('temp.txt', 'w') as f: +# f.write(content) + +# ...and re-open it each time +# with open('temp.txt') as f: +# content = f.read() +try: + raw_initial_store_data = re.search(r'data-initial-stores="([^"]*)"', content)[1] +except: + print(content) + raise SystemExit + +menardses = json.loads(raw_initial_store_data.replace(""", '"')) + +stores = [] +for menards in menardses: + stores.append({ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [float(menards['longitude']), float(menards['latitude'])], # yes, [lon, lat] since it's [x, y] + }, + "properties": { + 'address': menards['street'].title(), + 'city': menards['city'].title(), + 'state': menards['state'], + 'zip': menards['zip'], + 'website': f"https://www.menards.com/store-details/store.html?store={menards['number']}", + }, + }) + +geojson = { + "type": "FeatureCollection", + "features": stores, +} + +with open("menards-data.geojson", "w") as f: + f.write(json.dumps(geojson)) + +print(f"{len(menardses)} locations found") diff --git a/layers/menards/layer.js b/layers/menards/layer.js new file mode 100644 index 0000000..1ddc989 --- /dev/null +++ b/layers/menards/layer.js @@ -0,0 +1,24 @@ +import VectorLayer from 'ol/layer/Vector'; +import {Vector as VectorSource} from 'ol/source.js'; +import GeoJSON from 'ol/format/GeoJSON.js'; + +import {Style, Stroke, Circle, Fill} from 'ol/style.js'; +import Icon from 'ol/style/Icon.js'; + +import menardsURL from '/data/menards-data.geojson?url'; // TODO: remove `?url`? +import pinURL from '/layers/menards/pin.svg?url'; // TODO: remove `?url`? + +const vectorLayer = new VectorLayer({ + source: new VectorSource({ + url: menardsURL, + format: new GeoJSON, + }), + style: new Style({ + image: new Icon({ + anchor: [0.5, 1], + src: pinURL, + }), + }), +}); + +export default vectorLayer; diff --git a/layers/menards/pin.svg b/layers/menards/pin.svg new file mode 100644 index 0000000..86aba5f --- /dev/null +++ b/layers/menards/pin.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + +