diff --git a/samples/boundaries-click/index.ts b/samples/boundaries-click/index.ts index ad06279873..2ac3fc9d1b 100644 --- a/samples/boundaries-click/index.ts +++ b/samples/boundaries-click/index.ts @@ -7,86 +7,126 @@ // [START maps_boundaries_click_event] let map: google.maps.Map; let featureLayer; -let infoWindow: google.maps.InfoWindow; -async function initMap() { - // Request needed libraries. - const { Map, InfoWindow } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary; - - map = new Map(document.getElementById('map') as HTMLElement, { - center: { lat: 39.23, lng: -105.73 }, // Park County, CO - zoom: 8, - // In the cloud console, configure this Map ID with a style that enables the - // "Administrative Area Level 2" Data Driven Styling type. - mapId: 'a3efe1c035bad51b', // , - }); - //[START maps_boundaries_click_event_add_layer] - // Add the feature layer. - //@ts-ignore - featureLayer = map.getFeatureLayer('ADMINISTRATIVE_AREA_LEVEL_2'); - // Add the event listener for the feature layer. - featureLayer.addListener('click', handlePlaceClick); - //[END maps_boundaries_click_event_add_layer] - infoWindow = new InfoWindow({}); - // Apply style on load, to enable clicking. - applyStyleToSelected(); -} +let infoWindow; +let lastInteractedFeatureIds = []; +let lastClickedFeatureIds = []; + // [START maps_boundaries_click_event_handler] -// Handle the click event. -async function handlePlaceClick(event) { - let feature = event.features[0]; - if (!feature.placeId) return; - // Apply the style to the feature layer. - applyStyleToSelected(feature.placeId); - // Add the info window. - const place = await feature.fetchPlace(); - let content = 'Display name: ' + place.displayName + - '
Place ID: ' + feature.placeId + - '
Feature type: ' + feature.featureType + - '
'; - updateInfoWindow(content, event.latLng); +function handleClick(/* MouseEvent */ e) { + lastClickedFeatureIds = e.features.map(f => f.placeId); + lastInteractedFeatureIds = []; + featureLayer.style = applyStyle; + createInfoWindow(e); +} + +function handleMouseMove(/* MouseEvent */ e) { + lastInteractedFeatureIds = e.features.map(f => f.placeId); + featureLayer.style = applyStyle; } // [END maps_boundaries_click_event_handler] + +async function initMap() { + // Request needed libraries. + const { Map, InfoWindow } = await google.maps.importLibrary('maps') as google.maps.MapsLibrary; + + map = new Map(document.getElementById('map') as HTMLElement, { + center: {lat: 39.23, lng: -105.73}, + zoom: 8, + // In the cloud console, configure your Map ID with a style that enables the + // 'Administrative Area Level 2' Data Driven Styling type. + mapId: 'a3efe1c035bad51b', // Substitute your own map ID. + mapTypeControl: false, + }); + + //[START maps_boundaries_click_event_add_layer] + // Add the feature layer. + //@ts-ignore + featureLayer = map.getFeatureLayer('ADMINISTRATIVE_AREA_LEVEL_2'); + + // Add the event listeners for the feature layer. + featureLayer.addListener('click', handleClick); + featureLayer.addListener('mousemove', handleMouseMove); + + // Map event listener. + map.addListener('mousemove', () => { + // If the map gets a mousemove, that means there are no feature layers + // with listeners registered under the mouse, so we clear the last + // interacted feature ids. + if (lastInteractedFeatureIds?.length) { + lastInteractedFeatureIds = []; + featureLayer.style = applyStyle; + } + }); + //[END maps_boundaries_click_event_add_layer] + + // Create the infowindow. + infoWindow = new InfoWindow({}); + // Apply style on load, to enable clicking. + featureLayer.style = applyStyle; +} + +// Helper function for the infowindow. +async function createInfoWindow(event) { + let feature = event.features[0]; + if (!feature.placeId) return; + + // Update the infowindow. + const place = await feature.fetchPlace(); + let content = + 'Display name: ' + place.displayName + + '
Place ID: ' + feature.placeId + + '
Feature type: ' + feature.featureType + '
'; + + updateInfoWindow(content, event.latLng); +} + // [START maps_boundaries_click_event_style] +// Define styles. // Stroke and fill with minimum opacity value. -//@ts-ignore -const styleDefault: google.maps.FeatureStyleOptions = { - strokeColor: '#810FCB', - strokeOpacity: 1.0, - strokeWeight: 2.0, - fillColor: 'white', - fillOpacity: 0.1 // Polygons must be visible to receive click events. +const styleDefault = { + strokeColor: '#810FCB', + strokeOpacity: 1.0, + strokeWeight: 2.0, + fillColor: 'white', + fillOpacity: 0.1, // Polygons must be visible to receive events. }; - -// Style for the clicked Administrative Area Level 2 polygon. -//@ts-ignore -const styleClicked: google.maps.FeatureStyleOptions = { - ...styleDefault, - fillColor: '#810FCB', - fillOpacity: 0.5 +// Style for the clicked polygon. +const styleClicked = { + ...styleDefault, + fillColor: '#810FCB', + fillOpacity: 0.5, }; -// [END maps_boundaries_click_event_style] -// Apply styles to the map. -function applyStyleToSelected(placeid?) { - // Apply styles to the feature layer. - featureLayer.style = (options) => { - // Style fill and stroke for a polygon. - if (placeid && options.feature.placeId == placeid) { - return styleClicked; - } - // Style only the stroke for the entire feature type. - return styleDefault; - }; +// Style for polygon on mouse move. +const styleMouseMove = { + ...styleDefault, + strokeWeight: 4.0, +}; + +// Apply styles using a feature style function. +function applyStyle(/* FeatureStyleFunctionOptions */ params) { + const placeId = params.feature.placeId; + //@ts-ignore + if (lastClickedFeatureIds.includes(placeId)) { + return styleClicked; + } + //@ts-ignore + if (lastInteractedFeatureIds.includes(placeId)) { + return styleMouseMove; + } + return styleDefault; } +// [END maps_boundaries_click_event_style] + // Helper function to create an info window. function updateInfoWindow(content, center) { - infoWindow.setContent(content); - infoWindow.setPosition(center); - infoWindow.open({ - map, - shouldFocus: false, - }); + infoWindow.setContent(content); + infoWindow.setPosition(center); + infoWindow.open({ + map, + shouldFocus: false, + }); } initMap(); -// [END maps_boundaries_click_event] +// [END maps_boundaries_click_event] export { }; diff --git a/samples/dds-datasets-polygon-click/index.ts b/samples/dds-datasets-polygon-click/index.ts index 5c8b4e7a4c..a0f8fdaf95 100644 --- a/samples/dds-datasets-polygon-click/index.ts +++ b/samples/dds-datasets-polygon-click/index.ts @@ -3,90 +3,124 @@ * Copyright 2019 Google LLC. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ - // [START maps_dds_datasets_polygon_click] -let map; +let map: google.maps.Map; +let lastInteractedFeatureIds = []; let lastClickedFeatureIds = []; let datasetLayer; // [START maps_dds_datasets_polygon_click_eventhandler] -function handleClick( /* MouseEvent */ e) { +// Note, 'globalid' is an attribute in this Dataset. +function handleClick(/* MouseEvent */ e) { if (e.features) { lastClickedFeatureIds = - // Note, 'globalid' is an attribute in this Dataset. - e.features.map(f => f.datasetAttributes['globalid']); + e.features.map((f) => f.datasetAttributes['globalid']); + } + //@ts-ignore + datasetLayer.style = applyStyle; +} + +function handleMouseMove(/* MouseEvent */ e) { + if (e.features) { + lastInteractedFeatureIds = + e.features.map((f) => f.datasetAttributes['globalid']); } //@ts-ignore - datasetLayer.style = setStyle; + datasetLayer.style = applyStyle; } // [END maps_dds_datasets_polygon_click_eventhandler] -// [START maps_dds_datasets_polygon_click_stylefunction] -function setStyle(/* FeatureStyleFunctionOptions */ params) { - const datasetFeature = params.feature; +async function initMap() { + // Request needed libraries. + const { Map } = await google.maps.importLibrary('maps') as google.maps.MapsLibrary; + const { LatLng } = await google.maps.importLibrary('core') as google.maps.CoreLibrary; + const position = new LatLng(40.796675, -73.946275); + map = new Map(document.getElementById('map') as HTMLElement, { + zoom: 13, + center: position, + mapId: 'b98e588c46685dd7', + mapTypeControl: false, + }); + + // Dataset ID for NYC park data. + const datasetId = '6fe13aa9-b900-45e7-b636-3236672c3f4f'; + + //@ts-ignore + // [START maps_dds_datasets_polygon_click_addlistener] + datasetLayer = map.getDatasetFeatureLayer(datasetId); + datasetLayer.style = applyStyle; + + datasetLayer.addListener('click', handleClick); + datasetLayer.addListener('mousemove', handleMouseMove); - // Note, 'globalid' is an attribute in this dataset. - //@ts-ignore - if (lastClickedFeatureIds.includes(datasetFeature.datasetAttributes['globalid'])) { - return /* FeatureStyleOptions */ { - strokeColor: 'blue', - strokeWeight: 2, - strokeOpacity: 1, - fillColor: 'blue', - fillOpacity: 0.5, - }; + // Map event listener. + map.addListener('mousemove', () => { + // If the map gets a mousemove, that means there are no feature layers + // with listeners registered under the mouse, so we clear the last + // interacted feature ids. + if (lastInteractedFeatureIds?.length) { + lastInteractedFeatureIds = []; + datasetLayer.style = applyStyle; } - return /* FeatureStyleOptions */ { - strokeColor: 'green', - strokeWeight: 2, - strokeOpacity: 1, - fillColor: 'green', - fillOpacity: 0.3, - }; + }); + // [END maps_dds_datasets_polygon_click_addlistener] + const attributionDiv = document.createElement('div'); + const attributionControl = createAttribution(map); + + attributionDiv.appendChild(attributionControl); + map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(attributionDiv); } -// [END maps_dds_datasets_polygon_click_stylefunction] -async function initMap() { - // Request needed libraries. - const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary; - const { LatLng } = await google.maps.importLibrary("core") as google.maps.CoreLibrary; - - const position = new LatLng(40.796675, -73.946275); - const map = new Map(document.getElementById('map') as HTMLElement, { - zoom: 13, - center: position, - mapId: 'b98e588c46685dd7', - mapTypeControl: false, - }); +// [START maps_dds_datasets_polygon_click_stylefunction] +const styleDefault = { + strokeColor: 'green', + strokeWeight: 2.0, + strokeOpacity: 1.0, + fillColor: 'green', + fillOpacity: 0.3, +}; + +const styleClicked = { + ...styleDefault, + strokeColor: 'blue', + fillColor: 'blue', + fillOpacity: 0.5, +}; - // Dataset ID for NYC park data. - const datasetId = '6fe13aa9-b900-45e7-b636-3236672c3f4f'; - //@ts-ignore - datasetLayer = map.getDatasetFeatureLayer(datasetId); - datasetLayer.style = setStyle; - // [START maps_dds_datasets_polygon_click_addlistener] - datasetLayer.addListener('click', handleClick); - // [END maps_dds_datasets_polygon_click_addlistener] +const styleMouseMove = { + ...styleDefault, + strokeWeight: 4.0 +}; - const attributionDiv = document.createElement('div'); - const attributionControl = createAttribution(map); - attributionDiv.appendChild(attributionControl); - map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(attributionDiv); +function applyStyle(/* FeatureStyleFunctionOptions */ params) { + const datasetFeature = params.feature; + // Note, 'globalid' is an attribute in this dataset. + //@ts-ignore + if (lastClickedFeatureIds.includes(datasetFeature.datasetAttributes['globalid'])) { + return styleClicked; + } + //@ts-ignore + if (lastInteractedFeatureIds.includes(datasetFeature.datasetAttributes['globalid'])) { + return styleMouseMove; + } + return styleDefault; } +// [END maps_dds_datasets_polygon_click_stylefunction] function createAttribution(map) { - const attributionLabel = document.createElement('div'); - // Define CSS styles. - attributionLabel.style.backgroundColor = '#fff'; - attributionLabel.style.opacity = '0.7'; - attributionLabel.style.fontFamily = 'Roboto,Arial,sans-serif'; - attributionLabel.style.fontSize = '10px'; - attributionLabel.style.padding = '2px'; - attributionLabel.style.margin = '2px'; - attributionLabel.textContent = 'Data source: NYC Open Data'; - return attributionLabel; + const attributionLabel = document.createElement('div'); + + // Define CSS styles. + attributionLabel.style.backgroundColor = '#fff'; + attributionLabel.style.opacity = '0.7'; + attributionLabel.style.fontFamily = 'Roboto,Arial,sans-serif'; + attributionLabel.style.fontSize = '10px'; + attributionLabel.style.padding = '2px'; + attributionLabel.style.margin = '2px'; + attributionLabel.textContent = 'Data source: NYC Open Data'; + return attributionLabel; } initMap(); // [END maps_dds_datasets_polygon_click] -export { }; \ No newline at end of file +export { };