mapcn-react-native
Data

GeoJSON

The foundational GeoJSON rendering primitive -- one native source, up to three geometry-filtered layers, selection highlighting, and feature press events.

Renderer support: MapLibre ✓  ·  Mapbox ✓

npx mapcn-rn add geojson
import { MapGeoJSON } from "@/components/ui/mapcn";

Overview

MapGeoJSON renders any GeoJSON input (a Feature, FeatureCollection, raw Geometry, or a GeoJSON string) through one native source and up to three base layers -- fill, line, and point (circle) -- each automatically filtered by geometry type, so a mixed FeatureCollection renders correctly with no per-type wiring on your part. MapClusterLayer, MapHeatmap, MapChoropleth, MapCircle, and MapPolygon are all built on this component or the same underlying MapSource/MapLayer primitives.

Every data primitive in mapcn renders through native map layers rather than React Native views -- this is what lets MapGeoJSON stay correct with tens of thousands of features where MapMarker would not.

Props

PropTypeDefaultDescription
idstringauto-generatedSource id, useful for referencing from sibling raw layers.
dataGeoJSONInputRequired. Feature | FeatureCollection | Geometry | string.
pointPointStyle | false{ color: "#4285F4", radius: 5, strokeColor: "#fff", strokeWidth: 1.5 }Point-geometry styling. false disables the layer.
lineLineStyle | false{ color: "#4285F4", width: 3 }Line-geometry styling.
fillFillStyle | false{ color: "#4285F4", opacity: 0.3, outlineColor: "#4285F4" }Polygon-geometry styling.
selected{ point?, line?, fill? }Styles applied to the selected feature only, rendered as an extra highlight layer per geometry type.
selectedIdstring | number | nullThe feature id to highlight, compared against idProperty.
idPropertystring"id"Feature property compared against selectedId.
filterExpressionA style-spec filter expression applied to every base layer.
minZoom / maxZoomnumberZoom range for the base layers.
beforeIdstringLayer id to insert these layers before.
onFeaturePress(event: MapFeaturePressEvent) => voidFires with the pressed coordinate, screen point, and features under it.
hitbox{ width: number; height: number }Enlarges the press hit area.
pointStyle / lineStyle / fillStyleRecord<string, unknown>Raw style escape hatches, merged last over the computed style.
childrenReactNodeExtra raw layers rendered against the same source.

Selection is implemented via a compiled filter expression (["==", ["get", idProperty], selectedId]) on a dedicated highlight layer, not native feature state -- Mapbox has setFeatureState, MapLibre RN does not, so mapcn uses the mechanism both renderers share.

Example

import { Map } from "@/components/ui/mapcn";
import { MapGeoJSON } from "@/components/ui/mapcn";

const parks: GeoJSON.FeatureCollection = {
  type: "FeatureCollection",
  features: [
    { type: "Feature", properties: { id: "gg" }, geometry: { type: "Polygon", coordinates: [[[-122.51, 37.77], [-122.45, 37.77], [-122.45, 37.77], [-122.51, 37.77]]] } },
  ],
};

export function GeoJSONExample() {
  return (
    <Map defaultViewport={{ center: [-122.48, 37.77], zoom: 13 }} className="flex-1">
      <MapGeoJSON
        data={parks}
        fill={{ color: "#22c55e", opacity: 0.4 }}
        line={{ color: "#16a34a", width: 2 }}
        point={false}
        selectedId="gg"
        selected={{ fill: { color: "#22c55e", opacity: 0.7 } }}
        onFeaturePress={(e) => console.log(e.features)}
      />
    </Map>
  );
}

Live example

Efficient marker rendering with data-driven styling, built directly on GeoJSONSource/Layer:

layer-markers example screenshot

Clustering · Circles · Polygons · Choropleths · Routes

On this page