From 8be068158fb27e3ab53d262c29ccf9c628fd939c Mon Sep 17 00:00:00 2001 From: JeremyJamesL Date: Sat, 7 Dec 2024 16:50:21 +0000 Subject: =?UTF-8?q?=F0=9F=93=A6=20NEW:=20MVC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++ image.png | Bin 0 -> 110158 bytes index.html | 6 ++- src/main.js | 150 ++++++++++++++++++++++++++++++++------------------------ src/refactor.js | 91 ++++++++++++++++++++++++++++++++++ 5 files changed, 185 insertions(+), 65 deletions(-) create mode 100644 image.png create mode 100644 src/refactor.js diff --git a/README.md b/README.md index 30b0f30..7fd9b9c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Current searches for pubs in the UK are a bit rubbish. This takes inspiration fr 7. Query Algolia with the bounds 8. Limit response fields, we only really need the geoloc 9. Remove all markers when looking the markers +10. Debounce the query ## To do: @@ -23,3 +24,5 @@ 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 + +![alt text](image.png) diff --git a/image.png b/image.png new file mode 100644 index 0000000..16f8a59 Binary files /dev/null and b/image.png differ diff --git a/index.html b/index.html index d645716..2795415 100644 --- a/index.html +++ b/index.html @@ -51,6 +51,10 @@

London Pubs - Algolia Map Search

+
+ Shape can be Rectangular or a + Polygon +
@@ -67,6 +71,6 @@ - + diff --git a/src/main.js b/src/main.js index c8e7122..19716e6 100644 --- a/src/main.js +++ b/src/main.js @@ -1,41 +1,20 @@ import { algoliasearch } from "algoliasearch"; -import { info } from "autoprefixer"; -import instantsearch from "instantsearch.js"; -import { searchBox, hits, configure } from "instantsearch.js/es/widgets"; const MAPS_KEY = "AIzaSyCtS6CiOrG95FhroSUdDJJokItndcMkrgc"; const ALGOLIA_KEY = "9fb3db0222f7b5aef0e2b30791ee6201"; const INDEX_NAME = "pubfinder"; const client = algoliasearch("YSWWVAX5RB", ALGOLIA_KEY); +// Elements +const polygonSelect = document.querySelector(".polygon"); +const rectangleSelect = document.querySelector(".rectangle"); + let markers = []; +let map; const algolia_params = { hitsPerPage: 1000, }; -// const search = instantsearch({ -// indexName: INDEX_NAME, -// searchClient, -// // onStateChange({ uiState, setUiState }) { -// // setUiState(uiState); -// // }, -// // probably want to set initial search state depending on the rectangle coords -// }); - -// cons - -// search.addWidgets([ -// searchBox({ -// container: "#searchbox", -// }), -// hits({ -// container: "#hits", -// }), -// configure({}), -// ]); - -let map; - const initialPolygonCoords = [ { lat: 51.555519, lng: -0.215208 }, { lat: 51.526021, lng: -0.021665 }, @@ -52,13 +31,12 @@ const london_bounds = { }; function removeMarkers() { - console.log("hi"); for (let i = 0; i < markers.length; i++) { markers[i].setMap(null); } } -async function initMap() { +async function initMap(shape) { const position = { lat: 51.508616, lng: -0.125319 }; const { Map, Polygon, Rectangle, InfoWindow } = @@ -80,52 +58,96 @@ async function initMap() { }, }); - const rectangle = new Rectangle({ - bounds: london_bounds, - editable: true, - draggable: true, - }); - - rectangle.setMap(map); - - rectangle.addListener("bounds_changed", async function () { + function handleBoundsChange(activeShape) { + console.log("happening"); removeMarkers(); - const { south, west, north, east } = rectangle.getBounds()?.toJSON(); + const { south, west, north, east } = activeShape.getBounds()?.toJSON(); const algolia_bounds = [north, east, south, west]; - const res = await client.searchSingleIndex({ - indexName: INDEX_NAME, - searchParams: { - ...algolia_params, - insideBoundingBox: [algolia_bounds], - attributesToRetrieve: ["_geoloc", "name"], - }, - }); - - res.hits.forEach((hit) => { - console.log("hitting again"); - const marker = new AdvancedMarkerElement({ - map: map, - position: { - lat: hit._geoloc.lat, - lng: hit._geoloc.lng, + function debounce(func, delay) { + let timer; + return function (...args) { + const context = this; + clearTimeout(timer); + timer = setTimeout(() => { + func.apply(context, args); + }, delay); + }; + } + + async function getSearch() { + const res = await client.searchSingleIndex({ + indexName: INDEX_NAME, + searchParams: { + ...algolia_params, + insideBoundingBox: [algolia_bounds], + attributesToRetrieve: ["_geoloc", "name"], }, }); - const window = new InfoWindow({ - content: hit.name, - }); + res.hits.forEach((hit) => { + const marker = new AdvancedMarkerElement({ + map: map, + position: { + lat: hit._geoloc.lat, + lng: hit._geoloc.lng, + }, + }); - marker.addListener("click", function () { - window.open({ - anchor: marker, - map, + const window = new InfoWindow({ + content: hit.name, }); + + marker.addListener("click", function () { + window.open({ + anchor: marker, + map, + }); + }); + + markers.push(marker); }); + } - markers.push(marker); + const doAll = debounce(getSearch, 500); + doAll(); + } + + if (shape === "rectangular") { + console.log("doing"); + const rectangle = new Rectangle({ + bounds: london_bounds, + editable: true, + draggable: true, }); - }); + + rectangle.setMap(map); + rectangle.addListener("bounds_changed", handleBoundsChange(rectangle)); + } else if (shape === "polygonular") { + const polygon = new Polygon({ + paths: initialPolygonCoords, + strokeColor: "#FF0000", + strokeOpacity: 0.8, + strokeWeight: 2, + fillColor: "#FF0000", + fillOpacity: 0.35, + editable: true, + draggable: true, + }); + + polygon.setMap(map); + polygon.addListener("bounds_changed", handleBoundsChange(polygon)); + } } -initMap(); +[rectangleSelect, polygonSelect].forEach((el) => { + el.addEventListener("click", function (e) { + if (e.target.classList.contains("rectangle")) { + initMap("rectangular"); + } else { + initMap("polygonular"); + } + }); +}); + +initMap("rectangular"); diff --git a/src/refactor.js b/src/refactor.js new file mode 100644 index 0000000..90c5c35 --- /dev/null +++ b/src/refactor.js @@ -0,0 +1,91 @@ +import { algoliasearch } from "algoliasearch"; +const ALGOLIA_KEY = "9fb3db0222f7b5aef0e2b30791ee6201"; +const INDEX_NAME = "pubfinder"; +const client = algoliasearch("YSWWVAX5RB", ALGOLIA_KEY); + +const algolia_params = { + hitsPerPage: 1000, +}; + +const dataController = (function () { + const londonBounds = { + north: 51.532, + south: 51.478, + east: -0.072, + west: -0.16, + }; + + const maxMapSpace = { + north: 51.74, + south: 51.27, + west: -0.51, + east: 0.23, + }; + + const centralPosition = { lat: 51.508616, lng: -0.125319 }; + + return { + londonBounds, + centralPosition, + maxMapSpace, + getSearchResults: async function () { + const res = await client.searchSingleIndex({ + indexName: INDEX_NAME, + searchParams: { + ...algolia_params, + insideBoundingBox: [londonBounds], + attributesToRetrieve: ["_geoloc", "name"], + }, + }); + }, + }; +})(); + +const interfaceController = (function () { + let markers = []; + let map; + return { + generateMap: async function (bounds, position, maxSpace) { + const { Map, Polygon, Rectangle, InfoWindow } = + await google.maps.importLibrary("maps"); + const { AdvancedMarkerElement } = await google.maps.importLibrary( + "marker" + ); + map = new Map(document.getElementById("map"), { + zoom: 4, + center: position, + mapId: "pub_map", + restriction: { + latLngBounds: maxSpace, + strictBounds: true, + }, + }); + + const rectangle = new Rectangle({ + bounds: bounds, + editable: true, + draggable: true, + }); + + rectangle.setMap(map); + }, + }; +})(); + +const controller = (function (dataCTRL, uiCTRL) { + const initialSetup = function () { + const londonBounds = dataCTRL.londonBounds; + const centralPoint = dataCTRL.centralPosition; + const mapBounds = dataCTRL.maxMapSpace; + uiCTRL.generateMap(londonBounds, centralPoint, mapBounds); + dataCTRL.getSearchResults(); + }; + + return { + init: function () { + initialSetup(); + }, + }; +})(dataController, interfaceController); + +controller.init(); -- cgit v1.2.3