Data

Remote Datasource

Connect your own API endpoint as a live datasource — Mapsemble fetches features on demand from your server.

Remote Datasource

Unlike CSV or Airtable imports that copy data into Mapsemble, a remote datasource keeps your data on your own server. Mapsemble calls your endpoint every time a user pans the map, zooms in or out, applies a filter, or pages through results. Your server returns the matching features and Mapsemble renders them.

This approach is ideal when:

  • Your dataset is large or changes frequently — no need to re-import after every update.
  • You already have a database — Drupal, WordPress, Laravel, a custom app — and want to expose it on a map.
  • Data must stay on your infrastructure — for compliance, licensing, or privacy reasons.

How it works

  1. Build an endpoint on your server that returns GeoJSON-like features.
  2. In Mapsemble, create or edit a map and choose Remote URL as the datasource type.
  3. Paste your endpoint URL and save. Mapsemble starts fetching features immediately.

Quick Start

The simplest possible endpoint returns a JSON object with a features array and a totalCount:

{
  "features": [
    {
      "type": "Feature",
      "id": "1",
      "geometry": {
        "type": "Point",
        "coordinates": [-3.703, 40.416]
      },
      "properties": {
        "label": "Madrid"
      }
    },
    {
      "type": "Feature",
      "id": "2",
      "geometry": {
        "type": "Point",
        "coordinates": [2.173, 41.385]
      },
      "properties": {
        "label": "Barcelona"
      }
    }
  ],
  "totalCount": 2
}

Three rules to remember:

  1. Every feature must have an id. This is the standard GeoJSON id field (at the feature level, not inside properties). Mapsemble uses it internally to track features across re-fetches and to identify features in remote marker, card, and popup endpoint requests. Use your primary key.
  2. Coordinates are [longitude, latitude] — GeoJSON order, not the Google Maps order.
  3. totalCount is required. It tells Mapsemble how many features match the current query so it can paginate correctly.

Connect to Mapsemble

  1. Create a new map (or open an existing one).
  2. Under Data Source, select Remote URL.
  3. Paste your endpoint URL (e.g. https://example.com/api/map-features).
  4. Click Save. Mapsemble will call your endpoint and display the returned features.

API Contract

Mapsemble appends query parameters to your URL. All parameters are optional — your endpoint should return sensible defaults when none are provided.

Query Parameters

Parameter Type Description
extent string A WKT POLYGON describing the visible map area, e.g. POLYGON((-4.5 39.5, 3.5 39.5, 3.5 42.0, -4.5 42.0, -4.5 39.5)).
offset int Number of features to skip (pagination). Defaults to 0.
limit int Maximum number of features to return. Defaults to the map's page size.
orderBy string Sorting type slug, e.g. entropy for geographic distribution.
filters string A JSON-encoded string of active filters (see Filters section below).

When no parameters are sent (the very first request), return all features. Mapsemble uses this initial response to calculate the map's starting bounds.

Response Format

{
  "features": [
    {
      "type": "Feature",
      "id": "node-42",
      "geometry": {
        "type": "Point",
        "coordinates": [-3.703, 40.416]
      },
      "properties": {
        "title": "Example Location",
        "field_category": "restaurant",
        "field_price": 25
      }
    }
  ],
  "totalCount": 1234
}
  • features — Array of feature objects. Each feature must have id (a stable unique identifier), geometry (with type and coordinates), and properties.
  • totalCount — The total number of features matching the current filters (ignoring offset/limit). Mapsemble uses this for pagination and the result count display.

Extent Filtering

The extent parameter is a WKT POLYGON with five coordinate pairs (the last repeats the first to close the ring). Coordinates are in longitude latitude order, separated by spaces, with pairs separated by commas:

POLYGON((-4.5 39.5, 3.5 39.5, 3.5 42.0, -4.5 42.0, -4.5 39.5))

This describes a bounding box. To extract min/max values:

  • min longitude = -4.5 (left)
  • max longitude = 3.5 (right)
  • min latitude = 39.5 (bottom)
  • max latitude = 42.0 (top)

Only return features whose coordinates fall within this bounding box.

Pagination

Mapsemble sends offset and limit to paginate through results:

  • offset=0&limit=25 — first page (features 1–25)
  • offset=25&limit=25 — second page (features 26–50)

Your totalCount must reflect the total number of matching features (not just the current page). Mapsemble uses it to know how many pages exist and when to stop requesting.

Filters

The filters parameter is a URL-encoded JSON string. The keys are filter slugs (configured in your Mapsemble map settings) and the values depend on the filter type:

Select filter (single value):

{"field_category": "cafe"}

Checkboxes filter (multiple values — match any):

{"field_category": ["cafe", "restaurant"]}

Range filter (numeric min/max):

{"field_price": {"min": 5, "max": 20}}

Text search:

{"title": "sol"}

Date range:

{"field_date": {"start": "2026-01-01", "end": "2026-12-31"}}

Combined filters (multiple filters at once):

{
  "field_category": ["cafe", "restaurant"],
  "field_price": {"min": 5, "max": 20},
  "title": "sol"
}

Apply all filters with AND logic — a feature must match every active filter to be included.

External Filters from the Host Page

When Mapsemble is embedded on a website, the host page can set its own filters using JavaScript — without using Mapsemble's built-in filter UI. These external filters are merged into the same filters JSON parameter that your endpoint already receives.

// Host page sets filters via the widget.js API
Mapsemble.setFilters('YOUR_MAP_ID', {
  category: 'restaurant',
  city: 'Madrid',
});

Your endpoint receives:

?filters={"category":"restaurant","city":"Madrid"}

If Mapsemble also has its own filters active (e.g. a date range filter configured in the map settings), both are merged:

?filters={"category":"restaurant","city":"Madrid","field_date":{"start":"2026-04-01","end":"2026-04-30"}}

Your endpoint doesn't need to distinguish between Mapsemble filters and host-page filters — they all arrive in the same filters parameter. Just decode the JSON and apply each key as a filter condition.

See the Widget.js Reference for the full setFilters() API.

Entropy Sorting

When orderBy=entropy is sent, Mapsemble expects geographically distributed results rather than clustered ones. Entropy sorting spreads features across the visible area so the first page gives a representative sample of the whole map. This is a specific orderBy value that Mapsemble sends when geographic distribution is desired.

Implementing entropy sorting is optional. If you skip it, Mapsemble still works correctly, but the first page of results may cluster in one area of the map (e.g. all features from the same city).


MySQL / MariaDB Reference

This section provides ready-to-use SQL patterns for a common setup: a Drupal-style geofield table with bounding-box columns (left, right, top, bottom).

Extent Filtering

Given a table with bbox columns (field_geo_left, field_geo_right, field_geo_top, field_geo_bottom) and point columns (field_geo_lon, field_geo_lat):

SELECT *
FROM map_features
WHERE field_geo_lon BETWEEN :min_lon AND :max_lon
  AND field_geo_lat BETWEEN :min_lat AND :max_lat

Where :min_lon, :max_lon, :min_lat, :max_lat are extracted from the WKT POLYGON as described in the Extent Filtering section above.

If your table stores bounding boxes per feature (e.g. polygons), use overlap logic instead:

SELECT *
FROM map_features
WHERE field_geo_right  >= :min_lon
  AND field_geo_left   <= :max_lon
  AND field_geo_top    >= :min_lat
  AND field_geo_bottom <= :max_lat

Entropy Sorting

MySQL 8.0+ / MariaDB 10.7+ — use ST_GeoHash with window functions:

SELECT *, ROW_NUMBER() OVER (
  PARTITION BY LEFT(ST_GeoHash(ST_PointFromText(
    CONCAT('POINT(', field_geo_lon, ' ', field_geo_lat, ')')
  ), 3), 3)
  ORDER BY RAND()
) AS geo_rank
FROM map_features
WHERE field_geo_lon BETWEEN :min_lon AND :max_lon
  AND field_geo_lat BETWEEN :min_lat AND :max_lat
ORDER BY geo_rank, ST_GeoHash(ST_PointFromText(
  CONCAT('POINT(', field_geo_lon, ' ', field_geo_lat, ')')
), 6)
LIMIT :limit OFFSET :offset

This groups features into geohash cells, numbers them within each cell, then interleaves the groups so the first results are spread across the map.

Fallback (all MySQL/MariaDB versions) — use a grid based on FLOOR:

SELECT *, FLOOR(field_geo_lon * 10) AS grid_x,
          FLOOR(field_geo_lat * 10) AS grid_y
FROM map_features
WHERE field_geo_lon BETWEEN :min_lon AND :max_lon
  AND field_geo_lat BETWEEN :min_lat AND :max_lat
ORDER BY (grid_x * 7 + grid_y * 13) MOD 1000, field_geo_lon
LIMIT :limit OFFSET :offset

The prime multipliers and modulo create a pseudo-random distribution across grid cells.

Filter Examples

Select filter (taxonomy term):

SELECT f.*
FROM map_features f
INNER JOIN feature_terms ft ON ft.feature_id = f.id
INNER JOIN terms t ON t.id = ft.term_id
WHERE t.name = :category

Range filter (numeric field):

SELECT *
FROM map_features
WHERE field_price BETWEEN :min_price AND :max_price

Performance Recommendations

  • Add a spatial or bbox index. At minimum, create a composite index on your longitude and latitude columns:

    CREATE INDEX idx_geo_bbox ON map_features (
      field_geo_lon, field_geo_lat
    );
    
  • Cache totalCount for expensive queries. If your dataset is large (100k+ rows) and filters are complex, consider caching the count in a summary table or using a separate COUNT(*) query with the same WHERE clause. Note: SQL_CALC_FOUND_ROWS is deprecated in MySQL 8.0.17+ and should be replaced with a separate COUNT(*) query.

  • Large datasets (1M+ rows). Consider MySQL spatial indexes with SPATIAL INDEX on a POINT column for better performance than bbox column comparisons.

Database Compatibility

Feature MySQL 5.7 MySQL 8.0+ MariaDB 10.6 MariaDB 10.7+ PostgreSQL
Extent filtering (bbox) Yes Yes Yes Yes Yes
Entropy (geohash + window) No Yes No Yes Yes
Entropy (FLOOR fallback) Yes Yes Yes Yes Yes
Spatial indexes Yes Yes Yes Yes Yes (PostGIS)