From 17b517b32d18271c7d91b1a2044847b75758507e Mon Sep 17 00:00:00 2001 From: Jason Irish Date: Fri, 13 Sep 2024 14:18:19 -0500 Subject: [PATCH] Populate JSON file --- _config/config.yml | 6 +- dist/js/map.js | 101 ++++++++++-------- src/Control/ElementLocationsController.php | 55 ++-------- src/Element/ElementLocations.php | 3 +- .../LocationCategoryDataExtension.php | 3 +- src/Extension/LocationDataExtension.php | 34 ++++++ .../Dynamic/Elements/Locations/Data/JSON.ss | 27 +++++ 7 files changed, 138 insertions(+), 91 deletions(-) create mode 100644 src/Extension/LocationDataExtension.php diff --git a/_config/config.yml b/_config/config.yml index 2f8912d..33aafb9 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -1,3 +1,7 @@ +Dynamic\Locations\Model\Location: + extensions: + - Dynamic\Elements\Locations\Extension\LocationDataExtension + Dynamic\Locations\Model\LocationCategory: extensions: - - Dynamic\Elements\Locaitons\Extension\LocationCategoryDataExtension \ No newline at end of file + - Dynamic\Elements\Locations\Extension\LocationCategoryDataExtension \ No newline at end of file diff --git a/dist/js/map.js b/dist/js/map.js index c5fb50f..5a13423 100644 --- a/dist/js/map.js +++ b/dist/js/map.js @@ -111,24 +111,33 @@ const mapStyle = [{ function initMap() { // Create the map. const map = new google.maps.Map(document.getElementById('map'), { - zoom: 7, - center: {lat: 52.632469, lng: -1.689423}, + zoom: 7, // Initial zoom, this will change based on locations + center: {lat: 52.632469, lng: -1.689423}, // Initial center, this will also change styles: mapStyle, }); + // Create a LatLngBounds object to calculate the map's bounds + const bounds = new google.maps.LatLngBounds(); + // Load the stores GeoJSON onto the map. - map.data.loadGeoJson('$link', {idPropertyName: 'storeid'}); + map.data.loadGeoJson('$link', {idPropertyName: 'storeid'}, function(features) { + // Once the GeoJSON is loaded, iterate over each feature + features.forEach(function(feature) { + // Get the feature's geometry (its location) + const geometry = feature.getGeometry(); - // Define the custom marker icons, using the store's "category". - // map.data.setStyle((feature) => { - // return { - // icon: { - // url: `img/icon_${feature.getProperty('category')}.png`, - // scaledSize: new google.maps.Size(64, 64), - // }, - // }; - // }); + // If the geometry is a point, extend the bounds to include this point + if (geometry.getType() === 'Point') { + const coordinates = geometry.get(); + bounds.extend(coordinates); // Extend the bounds to include this location + } + }); + // Fit the map's viewport to the bounds of the locations + map.fitBounds(bounds); + }); + + // Define the custom marker icons, using the store's "category". const apiKey = '$key'; const infoWindow = new google.maps.InfoWindow(); @@ -137,9 +146,10 @@ const mapStyle = [{ const category = event.feature.getProperty('category'); const name = event.feature.getProperty('name'); const description = event.feature.getProperty('description'); - const hours = event.feature.getProperty('hours'); - const phone = event.feature.getProperty('phone'); + const hours = event.feature.getProperty('hours') || 'Hours not available'; + const phone = event.feature.getProperty('phone') || 'Phone not available'; const position = event.feature.getGeometry().get(); + const content = sanitizeHTML`
@@ -163,7 +173,7 @@ const mapStyle = [{ const input = document.createElement('input'); const options = { types: ['address'], - componentRestrictions: {country: 'gb'}, + // componentRestrictions: {country: 'gb'}, }; card.setAttribute('id', 'pac-card'); @@ -248,36 +258,43 @@ const mapStyle = [{ // The returned list will be in the same order as the destinations list const service = new google.maps.DistanceMatrixService(); const getDistanceMatrix = - (service, parameters) => new Promise((resolve, reject) => { - service.getDistanceMatrix(parameters, (response, status) => { - if (status != google.maps.DistanceMatrixStatus.OK) { - reject(response); + (service, parameters) => new Promise((resolve, reject) => { + service.getDistanceMatrix(parameters, (response, status) => { + if (status != google.maps.DistanceMatrixStatus.OK) { + reject(response); + } else { + const distances = []; + const results = response.rows[0].elements; + + for (let j = 0; j < results.length; j++) { + const element = results[j]; + + // Check if distance is available before accessing it + if (element.distance) { + const distanceText = element.distance.text; + const distanceVal = element.distance.value; + const distanceObject = { + storeid: stores[j], + distanceText: distanceText, + distanceVal: distanceVal, + }; + distances.push(distanceObject); } else { - const distances = []; - const results = response.rows[0].elements; - for (let j = 0; j < results.length; j++) { - const element = results[j]; - const distanceText = element.distance.text; - const distanceVal = element.distance.value; - const distanceObject = { - storeid: stores[j], - distanceText: distanceText, - distanceVal: distanceVal, - }; - distances.push(distanceObject); - } - - resolve(distances); + console.log(`Distance not available for store ${stores[j]}`); } - }); - }); - - const distancesList = await getDistanceMatrix(service, { - origins: [origin], - destinations: destinations, - travelMode: 'DRIVING', - unitSystem: google.maps.UnitSystem.METRIC, + } + + resolve(distances); + } }); + }); + + const distancesList = await getDistanceMatrix(service, { + origins: [origin], + destinations: destinations, + travelMode: 'DRIVING', + unitSystem: google.maps.UnitSystem.$MeasurementUnit, + }); distancesList.sort((first, second) => { return first.distanceVal - second.distanceVal; diff --git a/src/Control/ElementLocationsController.php b/src/Control/ElementLocationsController.php index 716d7a8..0530bb4 100644 --- a/src/Control/ElementLocationsController.php +++ b/src/Control/ElementLocationsController.php @@ -32,6 +32,9 @@ class ElementLocationsController extends ElementController 'json', ]; + /** + * @config + */ protected function init() { parent::init(); @@ -60,10 +63,10 @@ public function json() { $this->getResponse()->addHeader("Content-Type", "application/json"); $data = new ArrayData([ - //"Locations" => $this->getLocations(), + "Locations" => $this->getLocations(), ]); - return $data->renderWith('Dynamic/Elements/Locations/Data/geoJSON'); + return $data->renderWith('Dynamic/Elements/Locations/Data/JSON'); } /** @@ -80,41 +83,18 @@ public function getKey() public function getLocations() { if (!$this->locations) { - $this->setLocations($this->request); + $this->setLocations(); } return $this->locations; } /** - * @param HTTPRequest|null $request - * * @return $this */ - public function setLocations(HTTPRequest $request = null) + public function setLocations() { - - if ($request === null) { - $request = $this->request; - } - - if ($this->Categories()->exists()) { - foreach ($this->Categories() as $category) { - $filter['Categories.ID'][] = $category->ID; - } - } - - $this->extend('updateLocatorFilter', $filter, $request); - - $filterAny = $this->config()->get('base_filter_any'); - $this->extend('updateLocatorFilterAny', $filterAny, $request); - - $exclude = $this->config()->get('base_exclude'); - $this->extend('updateLocatorExclude', $exclude, $request); - - $class = $this->data()->ClassName; - $locations = $class::get_locations($filter, $filterAny, $exclude); - $locations = DataToArrayListHelper::to_array_list($locations); + $locations = $this->data()->getLocationsList(); //allow for adjusting list post possible distance calculation $this->extend('updateLocationList', $locations); @@ -123,24 +103,6 @@ public function setLocations(HTTPRequest $request = null) $locations = $locations->sort('Distance'); } - if ($this->getShowRadius()) { - $radiusVar = $this->data()->config()->get('radius_var'); - - if ($radius = (int)$request->getVar($radiusVar)) { - $locations = $locations->filterByCallback(function ($location) use (&$radius) { - return $location->Distance <= $radius; - }); - } - } - - //allow for returning list to be set as - $this->extend('updateListType', $locations); - - $limit = $this->getLimit(); - if ($limit > 0) { - $locations = $locations->limit($limit); - } - $this->locations = $locations; return $this; @@ -167,4 +129,5 @@ public function Link($action = null): string return $segment; } + } diff --git a/src/Element/ElementLocations.php b/src/Element/ElementLocations.php index b5fd553..85adfde 100644 --- a/src/Element/ElementLocations.php +++ b/src/Element/ElementLocations.php @@ -17,6 +17,7 @@ /** * Class \Dynamic\Elements\Locations\Elements\ElementLocations * + * @property string $MeasurementUnit * @method ManyManyList|LocationCategory[] Categories() */ class ElementLocations extends BaseElement @@ -44,7 +45,7 @@ class ElementLocations extends BaseElement * @config */ private static array $db = [ - + 'MeasurementUnit' => 'Enum("IMPERIAL, METRIC", "IMPERIAL")', ]; /** diff --git a/src/Extension/LocationCategoryDataExtension.php b/src/Extension/LocationCategoryDataExtension.php index 6a5f1da..118cfb8 100644 --- a/src/Extension/LocationCategoryDataExtension.php +++ b/src/Extension/LocationCategoryDataExtension.php @@ -1,8 +1,9 @@ 'Text', + ]; + + /** + * @param FieldList $fields + */ + public function updateCMSFields(FieldList $fields): void + { + $fields->insertAfter( + 'Links', + $fields->dataFieldByName('Hours') + ); + } +} diff --git a/templates/Dynamic/Elements/Locations/Data/JSON.ss b/templates/Dynamic/Elements/Locations/Data/JSON.ss index e69de29..011a46f 100644 --- a/templates/Dynamic/Elements/Locations/Data/JSON.ss +++ b/templates/Dynamic/Elements/Locations/Data/JSON.ss @@ -0,0 +1,27 @@ +{ + "type": "FeatureCollection", + "features": [ + <% loop $Locations %> + { + "geometry": { + "type": "Point", + "coordinates": [ + $Lng, + $Lat + ] + }, + "type": "Feature", + "properties": { + <% if $Categories %>"category": "$Categories.First.Title.XML",<% end_if %> + <% if $Hours %>"hours": "10am - 6pm",<% end_if %> + <% if $Content %>"description": "$Content.XML",<% end_if %> + <% if $Title %>"name": "$Title.XML",<% end_if %> + <% if $PhoneNumbers %>"phone": "$Phonenumbers.First.Phone.XML",<% end_if %> + <% if $EmailAddresses %>"email": "$EmailAddresses.First.Email.XML",<% end_if %> + <% if $WebsiteLinks %>"website": "$WebsiteLinks.First.URL.XML",<% end_if %> + "storeid": "$ID.XML" + } + }<% if not $IsLast %>,<% end_if %> + <% end_loop %> + ] +} \ No newline at end of file