סקירה כללית
מגדירים שכבת תכונות שתגיב לאירועים mousemove
ו-click
, ומשתמשים בהם כדי להחזיר מידע על הגבול שבו לחצתם. המידע הזה כולל מזהה, שם מוצג וסוג תכונה. במפה לדוגמה הבאה מוצגים הגבולות של אזור אדמיניסטרטיבי ברמה 2, ויש בה קוד לטיפול באירועים שמגדיר את הסגנון של הפוליגונים על סמך האינטראקציה של המשתמש (mousemove
משנה את עובי הקו, click
מצללה את צבע הרקע וגורמת להצגת חלון מידע).
הפעלת אירועים של שכבת תכונות
כדי להפעיל אירועים בשכבת תכונות:
כדי לרשום שכבת תכונות לקבלת התראות על אירועים, צריך להפעיל את הפונקציה
addListener()
בשכבת התכונות לכל אירוע שרוצים לרשום. בדוגמה הזו, המפה מקבלת גם מאזין.TypeScript
// 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; } });
JavaScript
// 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; } });
מוסיפים קוד של טיפול באירועים כדי להגדיר סגנון לפוליגון שנבחר על סמך סוג האינטראקציה.
TypeScript
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; }
JavaScript
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; }
משתמשים בפונקציה של סגנון תכונה כדי להחיל סגנונות. הפונקציה של סגנון התכונה שמוצגת כאן מחילה סגנון באופן מותנה על סמך סוג האינטראקציה. כאן מוגדרים שלושה סגנונות: אחד להדגשת המסגרת ב-
mousemove
, אחד לשינוי הרקע ולהצגת חלון מידע ב-click
וסגנון ברירת המחדל.TypeScript
// Define styles. // Stroke and fill with minimum opacity value. 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 polygon. const styleClicked = { ...styleDefault, fillColor: '#810FCB', fillOpacity: 0.5, }; // 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; }
JavaScript
// Define styles. // Stroke and fill with minimum opacity value. 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 polygon. const styleClicked = { ...styleDefault, fillColor: "#810FCB", fillOpacity: 0.5, }; // 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; }
קוד לדוגמה מלא
TypeScript
let map: google.maps.Map; let featureLayer; let infoWindow; let lastInteractedFeatureIds = []; let lastClickedFeatureIds = []; 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; } 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, }); // 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; } }); // 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 = '<span style="font-size:small">Display name: ' + place.displayName + '<br/> Place ID: ' + feature.placeId + '<br/> Feature type: ' + feature.featureType + '</span>'; updateInfoWindow(content, event.latLng); } // Define styles. // Stroke and fill with minimum opacity value. 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 polygon. const styleClicked = { ...styleDefault, fillColor: '#810FCB', fillOpacity: 0.5, }; // 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; } // Helper function to create an info window. function updateInfoWindow(content, center) { infoWindow.setContent(content); infoWindow.setPosition(center); infoWindow.open({ map, shouldFocus: false, }); } initMap();
JavaScript
let map; let featureLayer; let infoWindow; let lastInteractedFeatureIds = []; let lastClickedFeatureIds = []; 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; } async function initMap() { // Request needed libraries. const { Map, InfoWindow } = await google.maps.importLibrary("maps"); map = new Map(document.getElementById("map"), { 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, }); // 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; } }); // 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 = '<span style="font-size:small">Display name: ' + place.displayName + "<br/> Place ID: " + feature.placeId + "<br/> Feature type: " + feature.featureType + "</span>"; updateInfoWindow(content, event.latLng); } // Define styles. // Stroke and fill with minimum opacity value. 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 polygon. const styleClicked = { ...styleDefault, fillColor: "#810FCB", fillOpacity: 0.5, }; // 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; } // Helper function to create an info window. function updateInfoWindow(content, center) { infoWindow.setContent(content); infoWindow.setPosition(center); infoWindow.open({ map, shouldFocus: false, }); } initMap();
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html> <head> <title>Handle Region Boundary Click Event</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map"></div> <!-- prettier-ignore --> <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))}) ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script> </body> </html>