google-mapskmlgeoxml3

Change font size of placemark's name when zooming


I'm using geoxml3 and Google map to display a KML file with some placemarks have names. I created the parser like this:

$(function() {
  var myOptions = {
    center: new google.maps.LatLng(105.4009049697155, 45.9307395294156),
    zoom: 15,
    mapTypeId: "satellite",
  };
  var map = new google.maps.Map(
    document.getElementById("map_canvas"),
    myOptions
  );

  var geoXml;

  function initialize() {
    geoXml = new geoXML3.parser({
      map: map,
      singleInfoWindow: false,
      processStyles: false,
      createMarker: createMarker,
      afterParse: useTheData,
    });
    var kml_string =
      '<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> <Document> <name>Test</name> <Folder id="kml_1"> <name>d_y_n04</name> <Folder id="test"><name>test</name> <Placemark id="kml_478"> <name>placemark name 1</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4016150599436,45.9305731100841,488.499999999993</coordinates> </Point> </Placemark> <Placemark id="kml_368"> <name>placemark name 2</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4009049697155,45.9307395294156,0</coordinates> </Point> </Placemark> <Placemark id="kml_305"> <name>placemark name 3</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.400948826637,45.93090719596221,0</coordinates> </Point> </Placemark> <Placemark id="kml_480"> <name>Placemark name 4</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4008685356762,45.9313055053092,244.499999999993</coordinates> </Point> </Placemark> <Placemark id="kml_289"> <name>Placemark name 5</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4112903957788,45.93645760034801,0</coordinates> </Point> </Placemark> <Placemark id="kml_478"> <name>Placemark name 7</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4016150599436,45.9305731100841,488.499999999993</coordinates> </Point> </Placemark> <Placemark id="kml_297"> <name>Placemark name 6</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.403974541921,45.9341462756221,0</coordinates> </Point> </Placemark> </Folder> </Folder> </Document> </kml>';

    geoXml.parseKmlString(kml_string);

    marker_event = google.maps.event.addListener(
      map,
      "zoom_changed",
      function() {
        display_markers();
      }
    );

    center_changed_event = map.addListener("center_changed", () => {
      display_markers();
    });

    function display_markers() {
      var mapBounds = map.getBounds();
      geoXml.docs[0].markers.forEach(function(marker) {
        var in_bounds = mapBounds.contains(marker.getPosition());
        marker.setVisible(in_bounds);
      });
      geoXml.docs[0].placemarks.forEach(function(placemark) {
        if (placemark.Point) {
          placemark.style.scale = 1;
        }
      });
    }
  }

  function createMarker(placemark, doc) {
    var markerOptions = {
      optimized: true,
      position: placemark.latlng,
      map: map,
      label: placemark.name,
      icon: {
        path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,
        scale: 4,
      },
      visible: true,
    };

    var marker = new google.maps.Marker(markerOptions);
    doc.markers.push(marker);

    return marker;
  }

  function useTheData(doc) {
    for (var i = 0; i < doc[0].placemarks.length; i++) {
      var placemark = doc[0].placemarks[i];
      if (placemark.polygon) {
        placemark.polygon.normalStyle = {
          strokeColor: "#ffff00",
          strokeWeight: 1,
          strokeOpacity: 0,
          fillColor: "#ffff00",
          fillOpacity: 0,
        };
        placemark.polygon.setOptions(placemark.polygon.normalStyle);
      }
    }
  }
  initialize();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Import KML</title>
</head>

<body>
  <div id="map_canvas" style="width:1000px; height:550px; border: 2px solid #3872ac;"></div>

</body>

</html>

<script src="https://maps.googleapis.com/maps/api/js?v=3&key=YOUR_API_KEY"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/geocodezip/geoxml3/master/polys/geoxml3.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/geocodezip/geoxml3/master/ProjectedOverlay.js"></script>

The problem is when zooming the map smaller the display name of placemarks override each other like this:

enter image description here

So I tried to resize those names by adding zoom_changed event then change the style's scale like this but it didn't work:

google.maps.event.addListener(map, "zoom_changed", function () {
        geoXml.docs[0].placemarks.forEach(function (placemark) {
          if (placemark.Point) {
            placemark.style.scale = 0.5;
          }
        });
      }
);

Please tell me what I'm doing wrong or is there a way to change the font size of placemark's names when zooming map.


Solution

  • My suggestion would be to hide the labels once the zoom is less than 17 (or whatever threshold you feel gives the best experience). You can use the code below to dynamically change the fontSize based on the zoom, if that is what you really want (but eventually the labels will be unreadable).

    One option to do that would be to set the fontSize of the label to "0px" when you want it hidden, set it to "14px" (the default size), when you want it shown:

      google.maps.event.addListener(map, "zoom_changed", function() {
        if (map.getZoom() < 17) {
          geoXml.docs[0].markers.forEach(function(placemark) {
            if (placemark.getMap() != null) { // only process markers that are shown
              var label = placemark.getLabel();
              console.log(label);
              if (typeof label === 'string') {
                var labelObj = {};
                labelObj.text = label;
                labelObj.fontSize = "0px"; // hide the label
                placemark.setLabel(labelObj);
              } else {
                label.fontSize = "0px";
                placemark.setLabel(label);
              }
    
            }
          });
        } else {
          geoXml.docs[0].markers.forEach(function(placemark) {
            if (placemark.getMap() != null) { // only process markers that are shown
              var label = placemark.getLabel();
              console.log(label);
              if (typeof label === 'string') {
                var labelObj = {};
                labelObj.text = label;
                label.fontSize = "14px";  // show the label at the default size
                placemark.setLabel(labelObj);
              } else {
                label.fontSize = "14px";
                placemark.setLabel(label);
              }
            }
          });
        }
      });
    

    $(function() {
      var myOptions = {
        center: new google.maps.LatLng(105.4009049697155, 45.9307395294156),
        zoom: 15,
        mapTypeId: "satellite",
      };
      var map = new google.maps.Map(
        document.getElementById("map_canvas"),
        myOptions
      );
      google.maps.event.addListener(map, "zoom_changed", function() {
        console.log("zoom=" + map.getZoom());
        if (map.getZoom() < 17) {
          geoXml.docs[0].markers.forEach(function(placemark) {
            if (placemark.getMap() != null) {
              var label = placemark.getLabel();
              console.log(label);
              if (typeof label === 'string') {
                var labelObj = {};
                labelObj.text = label;
                labelObj.fontSize = "0px";
                placemark.setLabel(labelObj);
              } else {
                label.fontSize = "0px";
                placemark.setLabel(label);
              }
    
            }
          });
        } else {
          geoXml.docs[0].markers.forEach(function(placemark) {
            if (placemark.getMap() != null) {
              var label = placemark.getLabel();
              console.log(label);
              if (typeof label === 'string') {
                var labelObj = {};
                labelObj.text = label;
                label.fontSize = "14px";
                placemark.setLabel(labelObj);
              } else {
                label.fontSize = "14px";
                placemark.setLabel(label);
              }
            }
          });
        }
      });
      var geoXml;
    
      function initialize() {
        geoXml = new geoXML3.parser({
          map: map,
          singleInfoWindow: false,
          processStyles: false,
          createMarker: createMarker,
          afterParse: useTheData,
        });
        var kml_string =
          '<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> <Document> <name>Test</name> <Folder id="kml_1"> <name>d_y_n04</name> <Folder id="test"><name>test</name> <Placemark id="kml_478"> <name>placemark name 1</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4016150599436,45.9305731100841,488.499999999993</coordinates> </Point> </Placemark> <Placemark id="kml_368"> <name>placemark name 2</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4009049697155,45.9307395294156,0</coordinates> </Point> </Placemark> <Placemark id="kml_305"> <name>placemark name 3</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.400948826637,45.93090719596221,0</coordinates> </Point> </Placemark> <Placemark id="kml_480"> <name>Placemark name 4</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4008685356762,45.9313055053092,244.499999999993</coordinates> </Point> </Placemark> <Placemark id="kml_289"> <name>Placemark name 5</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4112903957788,45.93645760034801,0</coordinates> </Point> </Placemark> <Placemark id="kml_478"> <name>Placemark name 7</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.4016150599436,45.9305731100841,488.499999999993</coordinates> </Point> </Placemark> <Placemark id="kml_297"> <name>Placemark name 6</name><style><LineStyle> <color>ff000000</color> </LineStyle></style><Point> <coordinates>105.403974541921,45.9341462756221,0</coordinates> </Point> </Placemark> </Folder> </Folder> </Document> </kml>';
    
        geoXml.parseKmlString(kml_string);
    
        marker_event = google.maps.event.addListener(
          map,
          "zoom_changed",
          function() {
            display_markers();
          }
        );
    
        center_changed_event = map.addListener("center_changed", () => {
          display_markers();
        });
    
        function display_markers() {
          var mapBounds = map.getBounds();
          geoXml.docs[0].markers.forEach(function(marker) {
            var in_bounds = mapBounds.contains(marker.getPosition());
            marker.setVisible(in_bounds);
          });
          geoXml.docs[0].placemarks.forEach(function(placemark) {
            if (placemark.Point) {
              placemark.style.scale = 1;
            }
          });
        }
      }
    
      function createMarker(placemark, doc) {
        var markerOptions = {
          optimized: true,
          position: placemark.latlng,
          map: map,
          label: placemark.name,
          icon: {
            path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,
            scale: 4,
          },
          visible: true,
        };
    
        var marker = new google.maps.Marker(markerOptions);
        doc.markers.push(marker);
    
        return marker;
      }
    
      function useTheData(doc) {
        for (var i = 0; i < doc[0].placemarks.length; i++) {
          var placemark = doc[0].placemarks[i];
          if (placemark.polygon) {
            placemark.polygon.normalStyle = {
              strokeColor: "#ffff00",
              strokeWeight: 1,
              strokeOpacity: 0,
              fillColor: "#ffff00",
              fillOpacity: 0,
            };
            placemark.polygon.setOptions(placemark.polygon.normalStyle);
          }
        }
      }
      initialize();
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Import KML</title>
    </head>
    
    <body>
      <div id="map_canvas" style="width:1000px; height:550px; border: 2px solid #3872ac;"></div>
    
    </body>
    
    </html>
    
    <script src="https://maps.googleapis.com/maps/api/js?v=3&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/geocodezip/geoxml3/master/polys/geoxml3.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/geocodezip/geoxml3/master/ProjectedOverlay.js"></script>