שכבת נתונים

הפלטפורמה: Android iOS JavaScript

שכבת הנתונים של מפות Google מספקת מאגר לנתונים גיאו-מרחביים שרירותיים. אפשר להשתמש בשכבת הנתונים כדי לאחסן נתונים מותאמים אישית או כדי להציג נתוני GeoJSON במפת Google.

סקירה כללית

כדאי לצפות בסרטון הזה של DevBytes כדי לקבל מידע נוסף על שכבת הנתונים.

באמצעות Maps JavaScript API אפשר להוסיף למפה מגוון שכבות-על, כמו סמנים, קווים שבורים, מצולעים וכו'. כל אחת מההערות האלה משלבת מידע על סגנון עם נתוני מיקום. הסיווג google.maps.Data הוא מאגר לנתונים גיאו-מרחביים שרירותיים. במקום להוסיף את שכבות העל האלה, אפשר להשתמש בשכבת הנתונים כדי להוסיף נתונים גיאוגרפיים שרירותיים למפה. אם הנתונים האלה מכילים גיאומטריות, כמו נקודות, קווים או מצולעים, ה-API יעבד אותם כסמנים, כקווי פוליגון וכמצולעים. אפשר להחיל סגנונות על התכונות האלה כמו על שכבת-על רגילה, או להחיל כללי סגנון על סמך מאפיינים אחרים שנכללים במערך הנתונים.

בכיתה google.maps.Data אפשר:

  • לשרטט פוליגונים במפה.
  • הוספת נתוני GeoJSON למפה
    ‫GeoJSON הוא תקן לנתונים גיאו-מרחביים באינטרנט. המחלקות Data פועלות לפי המבנה של GeoJSON בייצוג הנתונים שלהן, וקל להציג איתן נתוני GeoJSON. אפשר להשתמש בשיטת loadGeoJson() כדי לייבא בקלות נתוני GeoJSON ולהציג נקודות, מחרוזות קו ומצולעים.
  • שימוש ב-google.maps.Data כדי ליצור מודל של נתונים שרירותיים.
    לרוב הישויות בעולם האמיתי יש מאפיינים אחרים שמשויכים אליהן. לדוגמה, לחנויות יש שעות פתיחה, בכבישים יש מהירות תנועה, ולכל קבוצת צופות יש אזור משלה למכירת עוגיות. בעזרת google.maps.Data, אתם יכולים ליצור מודלים של הנכסים האלה ולעצב את הנתונים בהתאם.
  • בוחרים איך הנתונים יוצגו ומשנים את הבחירה תוך כדי העבודה.
    שכבת הנתונים מאפשרת לכם לקבל החלטות לגבי ההצגה החזותית של הנתונים והאינטראקציה איתם. לדוגמה, כשמסתכלים על מפה של חנויות נוחות, אפשר לבחור להציג רק את החנויות שמוכרות כרטיסים לתחבורה ציבורית.

שרטוט פוליגון

הכיתה Data.Polygon מטפלת בשבילים של פוליגונים בשבילכם. אפשר להעביר למאפיין הזה מערך של טבעת לינארית אחת או יותר, שמוגדרות כקואורדינטות של קו רוחב/אורך. הטבעת הלינארית הראשונה מגדירה את הגבול החיצוני של הפוליגון. אם מעבירים יותר מטבעת לינארית אחת, הטבעות הלינאריות השנייה והבאות משמשות להגדרת נתיבים פנימיים (חורים) במצולע.

בדוגמה הבאה נוצר פוליגון מלבני עם שני חורים:

TypeScript

// This example uses the Google Maps JavaScript API's Data layer
// to create a rectangular polygon with 2 holes in it.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 6,
      center: { lat: -33.872, lng: 151.252 },
    }
  );

  // Define the LatLng coordinates for the outer path.
  const outerCoords = [
    { lat: -32.364, lng: 153.207 }, // north west
    { lat: -35.364, lng: 153.207 }, // south west
    { lat: -35.364, lng: 158.207 }, // south east
    { lat: -32.364, lng: 158.207 }, // north east
  ];

  // Define the LatLng coordinates for an inner path.
  const innerCoords1 = [
    { lat: -33.364, lng: 154.207 },
    { lat: -34.364, lng: 154.207 },
    { lat: -34.364, lng: 155.207 },
    { lat: -33.364, lng: 155.207 },
  ];

  // Define the LatLng coordinates for another inner path.
  const innerCoords2 = [
    { lat: -33.364, lng: 156.207 },
    { lat: -34.364, lng: 156.207 },
    { lat: -34.364, lng: 157.207 },
    { lat: -33.364, lng: 157.207 },
  ];

  map.data.add({
    geometry: new google.maps.Data.Polygon([
      outerCoords,
      innerCoords1,
      innerCoords2,
    ]),
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example uses the Google Maps JavaScript API's Data layer
// to create a rectangular polygon with 2 holes in it.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 6,
    center: { lat: -33.872, lng: 151.252 },
  });
  // Define the LatLng coordinates for the outer path.
  const outerCoords = [
    { lat: -32.364, lng: 153.207 }, // north west
    { lat: -35.364, lng: 153.207 }, // south west
    { lat: -35.364, lng: 158.207 }, // south east
    { lat: -32.364, lng: 158.207 }, // north east
  ];
  // Define the LatLng coordinates for an inner path.
  const innerCoords1 = [
    { lat: -33.364, lng: 154.207 },
    { lat: -34.364, lng: 154.207 },
    { lat: -34.364, lng: 155.207 },
    { lat: -33.364, lng: 155.207 },
  ];
  // Define the LatLng coordinates for another inner path.
  const innerCoords2 = [
    { lat: -33.364, lng: 156.207 },
    { lat: -34.364, lng: 156.207 },
    { lat: -34.364, lng: 157.207 },
    { lat: -33.364, lng: 157.207 },
  ];

  map.data.add({
    geometry: new google.maps.Data.Polygon([
      outerCoords,
      innerCoords1,
      innerCoords2,
    ]),
  });
}

window.initMap = initMap;

טעינת GeoJSON

GeoJSON הוא תקן נפוץ לשיתוף נתונים גיאו-מרחביים באינטרנט. הוא קל משקל וקל לקריאה על ידי בני אדם, ולכן הוא אידיאלי לשיתוף ולעבודה משותפת. בעזרת שכבת הנתונים, אפשר להוסיף נתוני GeoJSON למפת Google בשורה אחת בלבד של קוד.

map.data.loadGeoJson('google.json');

לכל מפה יש אובייקט map.data, שמשמש כשכבת נתונים לנתונים גיאו-מרחביים שרירותיים, כולל GeoJSON. אפשר לטעון ולהציג קובץ GeoJSON באמצעות קריאה לשיטה loadGeoJSON() של האובייקט data. הדוגמה הבאה מראה איך להוסיף מפה ולטעון נתוני GeoJSON חיצוניים.

TypeScript

async function initMap() {
  (await google.maps.importLibrary("maps")) as google.maps.MapsLibrary;

  const mapElement = document.querySelector(
    "gmp-map"
  ) as google.maps.MapElement;

  let innerMap = mapElement.innerMap;

  innerMap.data.loadGeoJson("google.json");
}

initMap();

JavaScript

async function initMap() {
    (await google.maps.importLibrary("maps"));
    const mapElement = document.querySelector("gmp-map");
    let innerMap = mapElement.innerMap;
    innerMap.data.loadGeoJson("google.json");
}
initMap();
לצפייה בדוגמה

דוגמה לניסיון

דוגמה ל-GeoJSON

רוב הדוגמאות בדף הזה משתמשות בקובץ GeoJSON משותף. הקובץ הזה מגדיר את ששת התווים במילה Google כמצולעים מעל אוסטרליה. אתם יכולים להעתיק את הקובץ הזה או לשנות אותו כשאתם בודקים את שכבת הנתונים.

הערה: כדי לטעון קובץ JSON מדומיין אחר, צריך להפעיל בדומיין הזה שיתוף משאבים בין מקורות שונים.

כדי לראות את הטקסט המלא של הקובץ, לוחצים על החץ הקטן שלצד המילים google.json.

google.json

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "letter": "G",
        "color": "blue",
        "rank": "7",
        "ascii": "71"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [123.61, -22.14], [122.38, -21.73], [121.06, -21.69], [119.66, -22.22], [119.00, -23.40],
            [118.65, -24.76], [118.43, -26.07], [118.78, -27.56], [119.22, -28.57], [120.23, -29.49],
            [121.77, -29.87], [123.57, -29.64], [124.45, -29.03], [124.71, -27.95], [124.80, -26.70],
            [124.80, -25.60], [123.61, -25.64], [122.56, -25.64], [121.72, -25.72], [121.81, -26.62],
            [121.86, -26.98], [122.60, -26.90], [123.57, -27.05], [123.57, -27.68], [123.35, -28.18],
            [122.51, -28.38], [121.77, -28.26], [121.02, -27.91], [120.49, -27.21], [120.14, -26.50],
            [120.10, -25.64], [120.27, -24.52], [120.67, -23.68], [121.72, -23.32], [122.43, -23.48],
            [123.04, -24.04], [124.54, -24.28], [124.58, -23.20], [123.61, -22.14]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "letter": "o",
        "color": "red",
        "rank": "15",
        "ascii": "111"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [128.84, -25.76], [128.18, -25.60], [127.96, -25.52], [127.88, -25.52], [127.70, -25.60],
            [127.26, -25.79], [126.60, -26.11], [126.16, -26.78], [126.12, -27.68], [126.21, -28.42],
            [126.69, -29.49], [127.74, -29.80], [128.80, -29.72], [129.41, -29.03], [129.72, -27.95],
            [129.68, -27.21], [129.33, -26.23], [128.84, -25.76]
          ],
          [
            [128.45, -27.44], [128.32, -26.94], [127.70, -26.82], [127.35, -27.05], [127.17, -27.80],
            [127.57, -28.22], [128.10, -28.42], [128.49, -27.80], [128.45, -27.44]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "letter": "o",
        "color": "yellow",
        "rank": "15",
        "ascii": "111"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [131.87, -25.76], [131.35, -26.07], [130.95, -26.78], [130.82, -27.64], [130.86, -28.53],
            [131.26, -29.22], [131.92, -29.76], [132.45, -29.87], [133.06, -29.76], [133.72, -29.34],
            [134.07, -28.80], [134.20, -27.91], [134.07, -27.21], [133.81, -26.31], [133.37, -25.83],
            [132.71, -25.64], [131.87, -25.76]
          ],
          [
            [133.15, -27.17], [132.71, -26.86], [132.09, -26.90], [131.74, -27.56], [131.79, -28.26],
            [132.36, -28.45], [132.93, -28.34], [133.15, -27.76], [133.15, -27.17]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "letter": "g",
        "color": "blue",
        "rank": "7",
        "ascii": "103"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [138.12, -25.04], [136.84, -25.16], [135.96, -25.36], [135.26, -25.99], [135, -26.90],
            [135.04, -27.91], [135.26, -28.88], [136.05, -29.45], [137.02, -29.49], [137.81, -29.49],
            [137.94, -29.99], [137.90, -31.20], [137.85, -32.24], [136.88, -32.69], [136.45, -32.36],
            [136.27, -31.80], [134.95, -31.84], [135.17, -32.99], [135.52, -33.43], [136.14, -33.76],
            [137.06, -33.83], [138.12, -33.65], [138.86, -33.21], [139.30, -32.28], [139.30, -31.24],
            [139.30, -30.14], [139.21, -28.96], [139.17, -28.22], [139.08, -27.41], [139.08, -26.47],
            [138.99, -25.40], [138.73, -25.00 ], [138.12, -25.04]
          ],
          [
            [137.50, -26.54], [136.97, -26.47], [136.49, -26.58], [136.31, -27.13], [136.31, -27.72],
            [136.58, -27.99], [137.50, -28.03], [137.68, -27.68], [137.59, -26.78], [137.50, -26.54]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "letter": "l",
        "color": "green",
        "rank": "12",
        "ascii": "108"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [140.14,-21.04], [140.31,-29.42], [141.67,-29.49], [141.59,-20.92], [140.14,-21.04]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "letter": "e",
        "color": "red",
        "rank": "5",
        "ascii": "101"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [144.14, -27.41], [145.67, -27.52], [146.86, -27.09], [146.82, -25.64], [146.25, -25.04],
            [145.45, -24.68], [144.66, -24.60], [144.09, -24.76], [143.43, -25.08], [142.99, -25.40],
            [142.64, -26.03], [142.64, -27.05], [142.64, -28.26], [143.30, -29.11], [144.18, -29.57],
            [145.41, -29.64], [146.46, -29.19], [146.64, -28.72], [146.82, -28.14], [144.84, -28.42],
            [144.31, -28.26], [144.14, -27.41]
          ],
          [
            [144.18, -26.39], [144.53, -26.58], [145.19, -26.62], [145.72, -26.35], [145.81, -25.91],
            [145.41, -25.68], [144.97, -25.68], [144.49, -25.64], [144, -25.99], [144.18, -26.39]
          ]
        ]
      }
    }
  ]
}

עיצוב נתוני GeoJSON

משתמשים בשיטה Data.setStyle() כדי לציין איך הנתונים צריכים להיראות. השיטה setStyle() מקבלת ליטרל של אובייקט StyleOptions או פונקציה שמחשבת את הסגנון של כל תכונה.

כללי סגנון פשוטים

הדרך הכי פשוטה להגדיר סגנון לתכונות היא להעביר StyleOptions אובייקט ליטרלי ל-setStyle(). כך תגדירו סגנון יחיד לכל תכונה באוסף. חשוב לדעת: כל סוג של תכונה יכול להציג רק קבוצת משנה של האפשרויות הזמינות. כלומר, אפשר לשלב סגנונות של סוגי תכונות שונים באובייקט ליטרלי אחד. לדוגמה, בקטע הקוד שבהמשך מוגדרים גם icon בהתאמה אישית, שמשפיע רק על גיאומטריות של נקודות, וגם fillColor, שמשפיע רק על מצולעים.

map.data.setStyle({
  icon: '//example.com/path/to/image.png',
  fillColor: 'green'
});

מידע נוסף על שילובים תקפים של סגנונות ותכונות זמין במאמר אפשרויות סגנון.

בדוגמה הבאה מוצגת הגדרה של צבע המילוי והקווים של כמה תכונות באמצעות StyleOptions literal של אובייקט. שימו לב שכל המצולעים מעוצבים באותו אופן.

TypeScript

async function initMap() {
  (await google.maps.importLibrary("maps")) as google.maps.MapsLibrary;

  const mapElement = document.querySelector(
    "gmp-map"
  ) as google.maps.MapElement;

  const innerMap = mapElement.innerMap;

  // Load GeoJSON.
  google.maps.event.addListenerOnce(innerMap, "idle", () => {
    innerMap.data.loadGeoJson("google.json");
  });

  // Set the stroke width, and fill color for each polygon
  innerMap.data.setStyle({
    fillColor: "green",
    strokeWeight: 1,
  });
}

initMap();

JavaScript

async function initMap() {
    (await google.maps.importLibrary("maps"));
    const mapElement = document.querySelector("gmp-map");
    const innerMap = mapElement.innerMap;
    // Load GeoJSON.
    google.maps.event.addListenerOnce(innerMap, "idle", () => {
        innerMap.data.loadGeoJson("google.json");
    });
    // Set the stroke width, and fill color for each polygon
    innerMap.data.setStyle({
        fillColor: "green",
        strokeWeight: 1,
    });
}
initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
gmp-map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Data Layer: Styling</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
    <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </head>
  <body>
    <gmp-map center="-28,137" zoom="4"></gmp-map>
  </body>
</html>
לצפייה בדוגמה

דוגמה לניסיון

כללי סגנון הצהרתיים

אם רוצים לעדכן את הסגנון של מספר גדול של שכבות-על, כמו סמנים או קווים פוליגוניים, בדרך כלל צריך לעבור על כל שכבת-על במפה ולהגדיר את הסגנון שלה בנפרד. שכבת הנתונים מאפשרת להגדיר כללים באופן הצהרתי, והם יחולו על כל מערך הנתונים. כשהנתונים או הכללים מתעדכנים, הסגנון מוחל באופן אוטומטי על כל התכונות. אפשר להשתמש במאפייני תכונות כדי להתאים אישית את הסגנון שלהן.

לדוגמה, הקוד שלמטה מגדיר את הצבע של כל תו ב-google.json על ידי בדיקת המיקום שלו בערכת התווים של ASCII. במקרה הזה, קידדנו את מיקום התו יחד עם הנתונים.

// Color Capital letters blue, and lower case letters red.
// Capital letters are represented in ascii by values less than 91
map.data.setStyle(function(feature) {
    var ascii = feature.getProperty('ascii');
    var color = ascii > 91 ? 'red' : 'blue';
    return {
      fillColor: color,
      strokeWeight: 1
    };
});

הסרת סגנונות

כדי להסיר סגנונות שהוחלו, מעבירים לשיטה setStyles() אובייקט ריק.

// Remove custom styles.
map.data.setStyle({});

הפעולה הזו תסיר את כל הסגנונות המותאמים אישית שציינתם, והתכונות יוצגו באמצעות סגנונות ברירת המחדל. אם אתם רוצים להפסיק להציג את התכונות, צריך להגדיר את המאפיין visible של StyleOptions כ-false.

// Hide the Data layer.
map.data.setStyle({visible: false});

שינוי סגנונות ברירת המחדל

בדרך כלל, כללי סגנון מוחלים על כל תכונה בשכבת הנתונים. עם זאת, יש מקרים שבהם תרצו להחיל כללי עיצוב מיוחדים על תכונות ספציפיות. לדוגמה, כדי להדגיש תכונה בלחיצה.

כדי להחיל כללי סגנון מיוחדים, משתמשים בשיטה overrideStyle(). כל הנכסים שמשנים באמצעות השיטה overrideStyle() מוחלים בנוסף לסגנונות הגלובליים שכבר צוינו ב-setStyle(). לדוגמה, הקוד הבא ישנה את צבע המילוי של מצולע בלחיצה, אבל לא יגדיר סגנונות אחרים.

// Set the global styles.
map.data.setStyle({
  fillColor: 'green',
  strokeWeight: 3
});

// Set the fill color to red when the feature is clicked.
// Stroke weight remains 3.
map.data.addListener('click', function(event) {
   map.data.overrideStyle(event.feature, {fillColor: 'red'});
});

מתקשרים אל השיטה revertStyle() כדי להסיר את כל ההגדרות לשינוי הסגנון.

סגנון

האפשרויות שזמינות לעיצוב כל תכונה תלויות בסוג התכונה. לדוגמה, fillColor יוצג רק בגיאומטריות של פוליגונים, ואילו icon יוצג רק בגיאומטריות של נקודות. מידע נוסף זמין במאמרי העזרה בנושא StyleOptions.

זמין בכל הגיאומטריות

  • clickable: אם true, התכונה מקבלת אירועים של עכבר ומגע
  • visible: אם true, התכונה גלויה.
  • zIndex: כל התכונות מוצגות במפה לפי הסדר של zIndex, כאשר ערכים גבוהים יותר מוצגים לפני תכונות עם ערכים נמוכים יותר. הסמנים תמיד מוצגים לפני מחרוזות של קווים ומצולעים.

זמין בגיאומטריות של נקודות

  • cursor: סמן העכבר שיוצג כשמעבירים את העכבר מעל.
  • icon: סמל שיוצג עבור גיאומטריית הנקודה.
  • shape: מגדיר את מפת התמונה שמשמשת לזיהוי קליקים.
  • title: טקסט שמופיע כשמעבירים את העכבר מעל התמונה.

זמין בגיאומטריות של קווים

  • strokeColor: צבע הקו. יש תמיכה בכל הצבעים ב-CSS3, מלבד צבעים מורחבים עם שמות.
  • strokeOpacity: אטימות הקו בין 0.0 ל-1.0.
  • strokeWeight: רוחב הקו בפיקסלים.

זמין בגיאומטריות של פוליגונים

  • fillColor: צבע המילוי. יש תמיכה בכל הצבעים ב-CSS3, מלבד צבעים מורחבים עם שמות.
  • fillOpacity: מידת האטימות של המילוי בין 0.0 לבין 1.0.
  • strokeColor: צבע הקו. יש תמיכה בכל הצבעים ב-CSS3, מלבד צבעים מורחבים עם שמות.
  • strokeOpacity: אטימות הקו בין 0.0 ל-1.0.
  • strokeWeight: רוחב הקו בפיקסלים.

הוספת גורמים שמטפלים באירועים

תגובות לאירועים, כמו mouseup או mousedown. אתם יכולים להוסיף מאזינים לאירועים כדי לאפשר למשתמשים לקיים אינטראקציה עם הנתונים במפה. בדוגמה שלמטה, אנחנו מוסיפים אירוע של העברת העכבר מעל אלמנט, שמציג מידע על התכונה מתחת לסמן העכבר.

// Set mouseover event for each feature.
map.data.addListener('mouseover', function(event) {
  document.getElementById('info-box').textContent =
      event.feature.getProperty('letter');
});

אירועים בשכבת הנתונים

האירועים הבאים משותפים לכל התכונות, ללא קשר לסוג הגיאומטריה שלהן:

  • addfeature
  • click
  • dblclick
  • mousedown
  • mouseout
  • mouseover
  • mouseup
  • removefeature
  • removeproperty
  • rightclick
  • setgeometry
  • setproperty

מידע נוסף על האירועים האלה זמין במאמרי העזרה של המחלקה google.maps.data.

שינוי המראה באופן דינמי

אפשר להגדיר את הסגנון של שכבת הנתונים על ידי העברת פונקציה שמחשבת את הסגנון של כל מאפיין לשיטה google.maps.data.setStyle(). המערכת תקרא לפונקציה הזו בכל פעם שמאפייני התכונה יעודכנו.

בדוגמה הבאה, אנחנו מוסיפים event listener לאירוע click שמעדכן את המאפיין isColorful של התכונה. הסגנון של התכונה מתעדכן כדי לשקף את השינוי ברגע שהנכס מוגדר.

// Color each letter gray. Change the color when the isColorful property
// is set to true.
map.data.setStyle(function(feature) {
  var color = 'gray';
  if (feature.getProperty('isColorful')) {
    color = feature.getProperty('color');
  }
  return /** @type {!google.maps.Data.StyleOptions} */({
    fillColor: color,
    strokeColor: color,
    strokeWeight: 2
  });
});

// When the user clicks, set 'isColorful', changing the color of the letters.
map.data.addListener('click', function(event) {
  event.feature.setProperty('isColorful', true);
});

// When the user hovers, tempt them to click by outlining the letters.
// Call revertStyle() to remove all overrides. This will use the style rules
// defined in the function passed to setStyle()
map.data.addListener('mouseover', function(event) {
  map.data.revertStyle();
  map.data.overrideStyle(event.feature, {strokeWeight: 8});
});

map.data.addListener('mouseout', function(event) {
  map.data.revertStyle();
});