Skip to content

Point Marker

Point markers are one of the most common feature types on maps. The SDK provides simple and easy-to-use APIs to add, manage, and style point markers.

Adding Point Markers

Basic Usage

javascript
// Add a simple point marker
const featureId = sdk.addPoint(
  [116.3974, 39.9093], // Coordinates [longitude, latitude]
  { name: "Beijing" },      // Properties
);

console.log("Point marker ID:", featureId);

Custom Styles

javascript
// Add a point marker with custom styles
const featureId = sdk.addPoint(
  [116.3974, 39.9093],
  { name: "Beijing", type: "city" },
  {
    paint: {
      "circle-radius": 10,        // Circle radius
      "circle-color": "#ff0000",   // Circle color
      "circle-stroke-width": 2,    // Stroke width
      "circle-stroke-color": "#ffffff", // Stroke color
      "circle-opacity": 0.8,       // Opacity
    },
  }
);

Using Icons

javascript
// 1. Register icon
const img = new Image();
img.src = "path/to/icon.png";
img.onload = () => {
  sdk.registerIcon("my-icon", img, {
    pixelRatio: 1,
  });
  
  // 2. Add point marker using icon
  sdk.addSource("marker-source", {
    type: "geojson",
    data: {
      type: "Feature",
      geometry: {
        type: "Point",
        coordinates: [116.3974, 39.9093],
      },
      properties: {
        title: "Beijing",
      },
    },
  });
  
  // 3. Add layer
  sdk.addLayer({
    id: "marker-layer",
    source: "marker-source",
    type: "symbol",
    layout: {
      "icon-image": "my-icon",
      "icon-size": 1,
      "text-field": ["get", "title"],
      "text-offset": [0, 1.5],
    },
  });
};

Batch Adding Point Markers

Using GeoJSON Data

javascript
// Add multiple point markers
const geojson = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: {
        type: "Point",
        coordinates: [116.3974, 39.9093],
      },
      properties: { name: "Beijing" },
    },
    {
      type: "Feature",
      geometry: {
        type: "Point",
        coordinates: [121.4737, 31.2304],
      },
      properties: { name: "Shanghai" },
    },
  ],
};

sdk.addGeoJSON("cities-source", geojson);

// Add layer
sdk.addLayer({
  id: "cities-layer",
  source: "cities-source",
  type: "circle",
  paint: {
    "circle-radius": 8,
    "circle-color": "#007bff",
  },
});

Loop Adding

javascript
const cities = [
  { name: "Beijing", lng: 116.3974, lat: 39.9093 },
  { name: "Shanghai", lng: 121.4737, lat: 31.2304 },
  { name: "Guangzhou", lng: 113.2644, lat: 23.1291 },
];

cities.forEach((city) => {
  sdk.addPoint(
    [city.lng, city.lat],
    { name: city.name },
    {
      paint: {
        "circle-radius": 8,
        "circle-color": "#007bff",
      },
    }
  );
});

Updating Point Markers

Update Position

javascript
// Get feature and update
const feature = sdk.geoJSONManager.getFeature(featureId);
if (feature) {
  // Update coordinates
  feature.geometry.coordinates = [121.4737, 31.2304];
  
  // Update source data
  sdk.getSource("source-id").setData(updatedGeoJSON);
}

Update Style

javascript
// Update layer style
sdk.updateLayerStyle("point-layer", {
  paint: {
    "circle-color": "#ff0000",
    "circle-radius": 12,
  },
});

Update Properties

javascript
// Update feature properties
const source = sdk.getSource("source-id");
const data = source._data;

// Find corresponding feature and update properties
data.features.forEach((feature) => {
  if (feature.id === featureId) {
    feature.properties.name = "New Name";
  }
});

// Update source data
source.setData(data);

Deleting Point Markers

Delete Single Point Marker

javascript
// Method 1: Delete by layer ID
sdk.removeLayer(featureId);

// Method 2: Delete via GeoJSONManager
sdk.geoJSONManager.removeFeature(featureId);

Delete Multiple Point Markers

javascript
const featureIds = ["feature-1", "feature-2", "feature-3"];

featureIds.forEach((id) => {
  sdk.removeLayer(id);
});

Clear All Point Markers

javascript
// Delete entire layer
sdk.removeLayer("point-layer");

// Clear source data
sdk.getSource("source-id").setData({
  type: "FeatureCollection",
  features: [],
});

Point Marker Interactions

Click Event

javascript
// Listen to point marker click
sdk.on("click", "point-layer", (e) => {
  const feature = e.features[0];
  console.log("Clicked point marker:", feature.properties);
  
  // Show popup
  const popup = new navMap.Popup()
    .setLngLat(e.lngLat)
    .setHTML(`<h3>${feature.properties.name}</h3>`)
    .addTo(sdk.map);
});

Hover Effect

javascript
// Highlight on mouse hover
sdk.on("mouseenter", "point-layer", (e) => {
  sdk.getCanvas().style.cursor = "pointer";
  
  // Change style
  sdk.setPaintProperty("point-layer", "circle-color", "#ff0000");
});

sdk.on("mouseleave", "point-layer", () => {
  sdk.getCanvas().style.cursor = "";
  
  // Restore style
  sdk.setPaintProperty("point-layer", "circle-color", "#007bff");
});

Using ClickManager

javascript
// Use ClickManager to simplify click handling
sdk.clickObj.clickPopup(
  "point-layer",
  (feature) => {
    return `<h3>${feature.properties.name}</h3>
            <p>Coordinates: ${feature.geometry.coordinates.join(", ")}</p>`;
  },
  {
    anchor: "bottom",
    closeButton: true,
  }
);

Style Configuration

Basic Style Properties

javascript
sdk.addPoint(
  [116.3974, 39.9093],
  { name: "Beijing" },
  {
    paint: {
      "circle-radius": 10,              // Radius
      "circle-color": "#ff0000",         // Color
      "circle-stroke-width": 2,          // Stroke width
      "circle-stroke-color": "#ffffff",  // Stroke color
      "circle-opacity": 1.0,             // Opacity
      "circle-blur": 0,                 // Blur
    },
  }
);

Dynamic Styles

javascript
// Dynamically set color based on property value
sdk.addLayer({
  id: "dynamic-points",
  source: "points-source",
  type: "circle",
  paint: {
    "circle-radius": 8,
    "circle-color": [
      "case",
      ["==", ["get", "type"], "city"],
      "#ff0000",  // City: red
      ["==", ["get", "type"], "airport"],
      "#0000ff",  // Airport: blue
      "#00ff00",  // Other: green
    ],
  },
});

Adjust Size Based on Zoom Level

javascript
sdk.addLayer({
  id: "zoom-points",
  source: "points-source",
  type: "circle",
  paint: {
    "circle-radius": [
      "interpolate",
      ["linear"],
      ["zoom"],
      5, 5,   // Radius 5 at zoom level 5
      10, 10, // Radius 10 at zoom level 10
      15, 15, // Radius 15 at zoom level 15
    ],
  },
});

Clustering Display

For large numbers of point markers, clustering functionality can be used:

javascript
// Enable clustering
sdk.geoJSONManager.setClusteringEnabled(true);

// Configure clustering parameters
sdk.geoJSONManager.setClusteringConfig("points-source", {
  enabled: true,
  radius: 50,      // Clustering radius (pixels)
  maxZoom: 16,     // Maximum clustering zoom level
  minPoints: 3,    // Minimum clustering point count
});

// Add clustering layer style
sdk.addLayer({
  id: "clusters",
  source: "points-source",
  type: "circle",
  filter: ["has", "point_count"],
  paint: {
    "circle-color": [
      "step",
      ["get", "point_count"],
      "#51bbd6",
      100,
      "#f1f075",
      750,
      "#f28cb1",
    ],
    "circle-radius": [
      "step",
      ["get", "point_count"],
      20,
      100,
      30,
      750,
      40,
    ],
  },
});

// Clustering count label
sdk.addLayer({
  id: "cluster-count",
  source: "points-source",
  type: "symbol",
  filter: ["has", "point_count"],
  layout: {
    "text-field": "{point_count_abbreviated}",
    "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
    "text-size": 12,
  },
});

Complete Example

javascript
let sdk;

async function initMap() {
  sdk = new navMap.MapSDK({
    container: "map",
    center: [116.39, 39.9],
    zoom: 10,
  });

  sdk.on("loadComplete", () => {
    setupPointMarkers();
  });
}

function setupPointMarkers() {
  // 1. Add single point marker
  const pointId = sdk.addPoint(
    [116.3974, 39.9093],
    { name: "Beijing", type: "city" },
    {
      paint: {
        "circle-radius": 10,
        "circle-color": "#ff0000",
        "circle-stroke-width": 2,
        "circle-stroke-color": "#ffffff",
      },
    }
  );

  // 2. Batch add point markers
  const cities = [
    { name: "Beijing", lng: 116.3974, lat: 39.9093 },
    { name: "Shanghai", lng: 121.4737, lat: 31.2304 },
    { name: "Guangzhou", lng: 113.2644, lat: 23.1291 },
  ];

  cities.forEach((city) => {
    sdk.addPoint(
      [city.lng, city.lat],
      { name: city.name, type: "city" },
      {
        paint: {
          "circle-radius": 8,
          "circle-color": "#007bff",
        },
      }
    );
  });

  // 3. Add click event
  sdk.clickObj.clickPopup(
    pointId,
    (feature) => {
      return `<h3>${feature.properties.name}</h3>
              <p>Type: ${feature.properties.type}</p>`;
    },
    {
      anchor: "bottom",
      closeButton: true,
    }
  );

  // 4. Add hover effect
  sdk.on("mouseenter", pointId, () => {
    sdk.setPaintProperty(pointId, "circle-color", "#00ff00");
  });

  sdk.on("mouseleave", pointId, () => {
    sdk.setPaintProperty(pointId, "circle-color", "#ff0000");
  });
}

initMap();

Notes

  1. Coordinate Order: Coordinate format is [longitude, latitude], pay attention to the order
  2. Performance Optimization: Consider using clustering functionality for large numbers of point markers
  3. Style Timing: Ensure point markers are added after map loadComplete
  4. Memory Management: Unnecessary point markers should be deleted promptly to avoid memory leaks
  5. Icon Loading: When using icons, ensure icons are loaded before use