Draw GeoJSON points as markers with MapLibre GL (an open-source fork of Mapbox GL)

Geoapify returns results in GeoJSON format which is natively supported by most of the client-side map libraries. Our Geocoding API and Places API return a GeoJSON.FeatureCollection with Features with geometry type Point.

In this code sample, we would like to show how GeoJSON points can be added to a map and handled as map markers. This gives you more control and allows you to manage items individually. For example, you can implement selection or use different icons for places.

We use Marker Icons API to generate marker icons in this example.

The full version of the code sample you can find on JSFiddle.

1. Create a map and query places data

You can follow instructions of our previous code sample "Draw GeoJSON points as a layer" to create a map and get places data.

2. Add results as map markers

The GeoJSON.FeatureCollection returned by Geoapify Geocoding API and Places API contains GeoJSON.Feature items. Each item represents a separate location. So by iterating the features, we have access to individual places, their geometry, and properties.

MapLibre GL lets to set a DIV-element as a map marker icon. This allows using CSS-classes and properties:

 .my-marker {
  height: 46px;
  width: 31px;
  cursor: pointer;
 }

import { Map, NavigationControl, Popup, Marker } from 'https://cdn.skypack.dev/maplibre-gl';

// Store all added markers to be able remove them later
var markers = [];

fetch(placesUrl).then(response => response.json()).then(places => {
  showGeoJSONPoints(places);
});

function showGeoJSONPoints(geojson) {

  if (markers.length) {
    markers.forEach(marker => marker.remove());
    markers = [];
  }

  // each feature contains 1 place
  geojson.features.forEach((feature, index) => {
    var markerIcon = document.createElement('div');
    markerIcon.classList.add("my-marker");
    // Icon size: 31 x 46px, shadow adds: 4px
    markerIcon.style.backgroundImage = `url(https://api.geoapify.com/v1/icon/?type=awesome&color=%233f99b1&text=${index + 1}&noWhiteCircle&apiKey=${myAPIKey})`;

    var popup = new Popup({
        anchor: 'bottom',
        offset: [0, -42] // height - shadow
      })
      .setText(feature.properties.name);

    var marker = new Marker(markerIcon, {
        anchor: 'bottom',
        offset: [0, 4] // shadow
      })
      .setLngLat(feature.geometry.coordinates)
      .setPopup(popup)
      .addTo(map);

    markers.push(marker);
  });
}

Note, by default the marker anchor is center. So the center of your marker is attached to marker position. Change the anchor (for example, to bottom for a pin icon) to change the marker position. In addition, you need to set an offset if the marker icon contains a shadow. For example, 4px for the icon provided in this code sample.