aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremyJamesL <jeremyluscombe@gmail.com>2024-12-08 21:55:22 +0000
committerJeremyJamesL <jeremyluscombe@gmail.com>2024-12-08 21:55:22 +0000
commit9ab0832af07e3e40dbd3a27b9d6682953e174f0c (patch)
tree4bdb3229ef206453d769f4568d91d89ef518f421
parent244412bddc81c18879b47cf279159a69a516fa94 (diff)
📦 NEW: polygon
-rw-r--r--README.md2
-rw-r--r--index.html4
-rw-r--r--src/refactor.js190
3 files changed, 163 insertions, 33 deletions
diff --git a/README.md b/README.md
index 7fd9b9c..49e0b7d 100644
--- a/README.md
+++ b/README.md
@@ -24,5 +24,7 @@ Current searches for pubs in the UK are a bit rubbish. This takes inspiration fr
[] Change search client to just
[] Don't return \_highlightResult?
[] Run search on first load
+[] Clear listeners
+[] remove duplication of search requests when selecting shape
![alt text](image.png)
diff --git a/index.html b/index.html
index 2795415..b0dc362 100644
--- a/index.html
+++ b/index.html
@@ -52,8 +52,8 @@
<div class="container">
<h1>London Pubs - Algolia Map Search</h1>
<div>
- Shape can be <span class="rectangle">Rectangular</span> or a
- <span class="polygon">Polygon</span>
+ Shape can be <span class="select--rectangle">Rectangular</span> or a
+ <span class="select--polygon">Polygon</span>
</div>
</div>
</header>
diff --git a/src/refactor.js b/src/refactor.js
index 37a96a0..9374402 100644
--- a/src/refactor.js
+++ b/src/refactor.js
@@ -2,7 +2,7 @@ import { algoliasearch } from "algoliasearch";
const ALGOLIA_KEY = "9fb3db0222f7b5aef0e2b30791ee6201";
const INDEX_NAME = "pubfinder";
const client = algoliasearch("YSWWVAX5RB", ALGOLIA_KEY);
-
+const $ = document.querySelector.bind(document);
const algolia_params = {
hitsPerPage: 1000,
};
@@ -14,7 +14,6 @@ const dataController = (function () {
east: -0.072,
west: -0.16,
};
-
const maxMapSpace = {
north: 51.74,
south: 51.27,
@@ -22,18 +21,38 @@ const dataController = (function () {
east: 0.23,
};
+ const initialPolygonBounds = [
+ { lat: 51.528125, lng: -0.104853 },
+ { lat: 51.519405, lng: -0.089005 },
+ { lat: 51.508742, lng: -0.108198 },
+ { lat: 51.507389, lng: -0.132242 },
+ { lat: 51.522659, lng: -0.134998 },
+ ];
+
const centralPosition = { lat: 51.508616, lng: -0.125319 };
return {
londonBounds,
centralPosition,
maxMapSpace,
- getSearchResults: async function (bounds) {
+ initialPolygonBounds,
+ getSearchResults: async function (shape, bounds) {
+ let geoParam;
+ if (shape === "rectangle") {
+ geoParam = {
+ insideBoundingBox: [bounds],
+ };
+ } else {
+ geoParam = {
+ insidePolygon: [bounds],
+ };
+ }
+
const res = await client.searchSingleIndex({
indexName: INDEX_NAME,
searchParams: {
...algolia_params,
- insideBoundingBox: [bounds],
+ ...geoParam,
attributesToRetrieve: ["_geoloc", "name"],
},
});
@@ -46,29 +65,53 @@ const interfaceController = (function () {
let markers = [];
let shape;
let map;
- return {
- generateMap: async function (bounds, position, maxSpace) {
- const { Map, Polygon, Rectangle } = await google.maps.importLibrary(
- "maps"
- );
- map = new Map(document.getElementById("map"), {
- zoom: 4,
- center: position,
- mapId: "pub_map",
- restriction: {
- latLngBounds: maxSpace,
- strictBounds: true,
- },
- });
+ const DOMStrings = {
+ selectRect: ".select--rectangle",
+ selectPoly: ".select--polygon",
+ };
+ const generateMap = async function (
+ bounds,
+ position,
+ maxSpace,
+ initialPolygonBounds,
+ currentShape
+ ) {
+ const { Map, Polygon, Rectangle } = await google.maps.importLibrary("maps");
+ map = new Map(document.getElementById("map"), {
+ zoom: 4,
+ center: position,
+ mapId: "pub_map",
+ restriction: {
+ latLngBounds: maxSpace,
+ strictBounds: true,
+ },
+ });
+ if (currentShape === "rectangle") {
shape = new Rectangle({
bounds: bounds,
editable: true,
draggable: true,
});
+ } else {
+ shape = new Polygon({
+ paths: initialPolygonBounds,
+ strokeColor: "#FF0000",
+ strokeOpacity: 0.8,
+ strokeWeight: 2,
+ fillColor: "#FF0000",
+ fillOpacity: 0.35,
+ editable: true,
+ draggable: true,
+ geodesic: true,
+ });
+ }
+ shape.setMap(map);
+ };
- shape.setMap(map);
- },
+ return {
+ handleShapeSelect: function (e) {},
+ initMap: generateMap,
embedSearchResults: async function (hits) {
const { AdvancedMarkerElement } = await google.maps.importLibrary(
"marker"
@@ -110,16 +153,29 @@ const interfaceController = (function () {
markers[i].setMap(null);
}
},
+ getDOMStrings: function () {
+ return DOMStrings;
+ },
};
})();
const controller = (function (dataCTRL, uiCTRL) {
+ const DOM = uiCTRL.getDOMStrings();
+ const londonBounds = dataCTRL.londonBounds;
+ const centralPoint = dataCTRL.centralPosition;
+ const mapBounds = dataCTRL.maxMapSpace; // This is rectangle bounds
+ const initialPolygonBounds = dataCTRL.initialPolygonBounds; // Polygon bound
+
const initialSetup = async function () {
- const londonBounds = dataCTRL.londonBounds;
- const centralPoint = dataCTRL.centralPosition;
- const mapBounds = dataCTRL.maxMapSpace;
- uiCTRL.generateMap(londonBounds, centralPoint, mapBounds);
- const searchResults = await dataCTRL.getSearchResults([
+ await uiCTRL.initMap(
+ londonBounds,
+ centralPoint,
+ mapBounds,
+ initialPolygonBounds,
+ "rectangle"
+ );
+
+ const searchResults = await dataCTRL.getSearchResults("rectangle", [
londonBounds.north,
londonBounds.east,
londonBounds.south,
@@ -128,21 +184,93 @@ const controller = (function (dataCTRL, uiCTRL) {
await uiCTRL.embedSearchResults(searchResults.hits);
};
- const setupEventListeners = function () {
+ const setupMapListeners = async function () {
const shape = uiCTRL.getActiveShape();
- shape.addListener("bounds_changed", async () => {
- uiCTRL.removeMarkers();
- const newAlgoliaBounds = uiCTRL.handleBoundChange();
- const searchResults = await dataCTRL.getSearchResults(newAlgoliaBounds);
+ if (shape instanceof google.maps.Rectangle) {
+ shape.addListener("dragend", async () => {
+ uiCTRL.removeMarkers();
+ const newAlgoliaBounds = uiCTRL.handleBoundChange();
+
+ const searchResults = await dataCTRL.getSearchResults(
+ "rectangle",
+ newAlgoliaBounds
+ );
+ await uiCTRL.embedSearchResults(searchResults.hits);
+ });
+ }
+
+ if (shape instanceof google.maps.Polygon) {
+ const paths = shape.getPaths();
+ let points = [];
+
+ const handlePathDrag = async function () {
+ uiCTRL.removeMarkers();
+ points = [];
+ paths.forEach((path) => {
+ path.forEach((latLng) => {
+ const lat = latLng.lat();
+ const lng = latLng.lng();
+ points.push(lat, lng);
+ });
+ });
+ const searchResults = await dataCTRL.getSearchResults(
+ "polygon",
+ points
+ );
+ await uiCTRL.embedSearchResults(searchResults.hits);
+ };
+
+ paths.forEach((path) => {
+ path.addListener("set_at", handlePathDrag);
+ path.addListener("insert_at", handlePathDrag);
+ });
+ }
+ };
+
+ const setupShapeSelectListeners = async function () {
+ $(DOM.selectRect).addEventListener("click", async () => {
+ await uiCTRL.initMap(
+ londonBounds,
+ centralPoint,
+ mapBounds,
+ initialPolygonBounds,
+ "rectangle"
+ );
+ const searchResults = await dataCTRL.getSearchResults("rectangle", [
+ londonBounds.north,
+ londonBounds.east,
+ londonBounds.south,
+ londonBounds.west,
+ ]);
+ await uiCTRL.embedSearchResults(searchResults.hits);
+ await setupMapListeners();
+ });
+ $(DOM.selectPoly).addEventListener("click", async () => {
+ await uiCTRL.initMap(
+ londonBounds,
+ centralPoint,
+ mapBounds,
+ initialPolygonBounds,
+ "polygon"
+ );
+ const translatedPolyBounds = initialPolygonBounds.flatMap(
+ ({ lat, lng }) => [lat, lng]
+ );
+ const searchResults = await dataCTRL.getSearchResults(
+ "polygon",
+ translatedPolyBounds
+ );
await uiCTRL.embedSearchResults(searchResults.hits);
+ await setupMapListeners();
});
};
return {
init: async function () {
await initialSetup();
- setupEventListeners();
+ await setupMapListeners();
+ await setupShapeSelectListeners();
},
};
})(dataController, interfaceController);