---
title: Polygon
source: https://vjmap.com/en/guide/polygon.html
---

# Polygon

## Usage

```js
let data = {
    "type": "FeatureCollection",
    "features": [
        {
            "id": "1",
            "type": "Feature",
            "properties": {
                "name": "polygon1",
                "color": "#00ffff"
            },
            "geometry": {
                "coordinates": [
                    [
                        [
                            3006.0952985307595,
                            15198.972934052355
                        ],
                        [
                            12606.64046359223,
                            9285.59366571666
                        ],
                        [
                            4745.324495099878,
                            3720.060236694666
                        ],
                        [
                            3006.0952985307595,
                            15198.972934052355
                        ]
                    ]
                ],
                "type": "Polygon"
            }
        },
        {
            "id": "2",
            "type": "Feature",
            "properties": {
                "name": "polygon2",
                "color": "#ff00ff"
            },
            "geometry": {
                "coordinates": [
                    [
                        [
                            19841.833921319492,
                            13807.589576796912
                        ],
                        [
                            19841.833921319492,
                            4207.0444117340885
                        ],
                        [
                            26172.62819683108,
                            4207.0444117340885
                        ],
                        [
                            26172.62819683108,
                            13807.589576796912
                        ],
                        [
                            19841.833921319492,
                            13807.589576796912
                        ]
                    ]
                ],
                "type": "Polygon"
            }
        }
    ]
}
let polygon = new vjmap.Polygon({
    data: map.toLngLat(data), // Convert CAD geometry coordinates to render longitude/latitude
    fillColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']],
    fillOpacity: 0.8,
    fillOutlineColor: "#f00",
    isHoverPointer: true,
    isHoverFeatureState: true
});
polygon.addTo(map);
polygon.clickLayer(e => map.logInfo(`You clicked No. ${e.features[0].id}, name: ${e.features[0].properties.name}, color: ${e.features[0].properties.color} `))
polygon.hoverPopup(f => `<h3>ID: ${f.properties.name}</h3>Color: ${f.properties.color}`, { anchor: 'bottom' });
```
<mapFrameEx>
<pre>
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
    mapid: "sys_hello", // Map ID
    mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry data rendering
    style: vjmap.openMapLightStyle() // Use dark background style when div has dark background
})
if (res.error) {
    // If open fails
    showError(res.error)
    return;
}
// Get map extent
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map extent
let prj = new vjmap.GeoProjection(mapBounds);
//
// Map object
let map = new vjmap.Map({
    container: 'map', // DIV container ID
    style: svc.rasterStyle(), // Style, raster style here
    center: prj.toLngLat(mapBounds.center()), // Set map center
    zoom: 1, // Set map zoom level
    pitch: 0,
    renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
map.attach(svc, prj);
await map.onLoad();
let data = {
    "type": "FeatureCollection",
    "features": [
        {
            "id": "1",
            "type": "Feature",
            "properties": {
                "name": "polygon1",
                "color": "#00ffff"
            },
            "geometry": {
                "coordinates": [
                    [
                        [
                            3006.0952985307595,
                            15198.972934052355
                        ],
                        [
                            12606.64046359223,
                            9285.59366571666
                        ],
                        [
                            4745.324495099878,
                            3720.060236694666
                        ],
                        [
                            3006.0952985307595,
                            15198.972934052355
                        ]
                    ]
                ],
                "type": "Polygon"
            }
        },
        {
            "id": "2",
            "type": "Feature",
            "properties": {
                "name": "polygon2",
                "color": "#ff00ff"
            },
            "geometry": {
                "coordinates": [
                    [
                        [
                            19841.833921319492,
                            13807.589576796912
                        ],
                        [
                            19841.833921319492,
                            4207.0444117340885
                        ],
                        [
                            26172.62819683108,
                            4207.0444117340885
                        ],
                        [
                            26172.62819683108,
                            13807.589576796912
                        ],
                        [
                            19841.833921319492,
                            13807.589576796912
                        ]
                    ]
                ],
                "type": "Polygon"
            }
        }
    ]
}
let polygon = new vjmap.Polygon({
    data: map.toLngLat(data), // Convert CAD geometry coordinates to render longitude/latitude
    fillColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']],
    fillOpacity: 0.8,
    fillOutlineColor: "#f00",
    isHoverPointer: true,
    isHoverFeatureState: true
});
polygon.addTo(map);
// Click event
polygon.clickLayer(e =&gt; map.logInfo(`You clicked No. ${e.features[0].id}, name: ${e.features[0].properties.name}, color: ${e.features[0].properties.color} `))
// Hover event
polygon.hoverPopup(f =&gt; `&lt;h3&gt;ID: ${f.properties.name}&lt;/h3&gt;Color: ${f.properties.color}`, { anchor: 'bottom' });
</pre>
</mapFrameEx>
<br/>
<br/>



Alternatively, create the data source first, then create the fill layer, e.g.
```js
map.addSource("fillSources", {
    type: "geojson",
    data: data
});
map.addLayer({
    id: 'fillLayers',
    source: 'fillSources',
    type: 'fill',
    "layout": {},
    "paint": {
        "fill-color": ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']], //color
        'fill-opacity': 0.8,
        'fill-outline-color': "#f00"
    }
})
```

Or use camelCase for properties, no need to distinguish layout vs paint

```js
map.addGeoJSONSource("fillSources", data);
map.addFillLayer("fillLayers", "fillSources", {
    fillColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']], //color
    fillOpacity: 0.8,
    fillOutlineColor: "#f00"
})
```

When using this approach of creating data source and layer, listen to `map layer events` for event handling

```js
map.on("click", layerId, e => {})
```

## Common Methods


Use `setData` to modify data
```js
polygon.setData(newDataJson);
```

Get layer ID and data source ID
```js
// Get layer ID
polygon.getLayerId()
// Get data source ID
polygon.getSourceId()
```


Show or hide
```js
// Show
polygon.show()
// Hide
polygon.hide()
```

Remove
```js
// Remove
polygon.remove()
```


## Related Examples

![image-20240928153704452](https://vjmap.com/blogimages/202409281537546.png)

[Single polygon](https://vjmap.com/demo/#/demo/map/overlay/polygon/01polygonSingle)

[Two polygons](https://vjmap.com/demo/#/demo/map/overlay/polygon/02polygonTwo)

[Batch draw polygons](https://vjmap.com/demo/#/demo/map/overlay/polygon/03polygonMany)

[Polygon conditional filter](https://vjmap.com/demo/#/demo/map/overlay/polygon/polygonFilter)

[Batch draw different types of polygons](https://vjmap.com/demo/#/demo/map/overlay/polygon/polygonManyType)

[Hollow polygon](https://vjmap.com/demo/#/demo/map/overlay/polygon/polygonMulti)

[Complex hollow polygon](https://vjmap.com/demo/#/demo/map/overlay/polygon/polygonMultiHole)

[Polygon pattern style](https://vjmap.com/demo/#/demo/map/overlay/polygon/polygonPattern)

[Polygon show line width on highlight](https://vjmap.com/demo/#/demo/map/overlay/polygon/polygonzHoverLineWidth)


## Type Definitions
```ts

/**
 * Create polygon.
 *
 **/
export  class Polygon extends OverlayLayerBase {
    options: PolygonOptions;
    constructor(options: PolygonOptions);
    addTo(map: Map, beforeId?: string): void;
    /** Replace the current data of the GeoJSON layer.
     @param {GeoJSON} [data] GeoJSON object to set. If not provided, defaults to an empty FeatureCollection.
     */
    setData(data: PointGeoJsonInput | PointGeoJsonInput[] | GeoJsonGeomertry | GeoPointLike | any): void;
    /** Set `fill-sort-key` layout property on one or more layers. */
    setFillSortKey(value: DataDrivenPropertyValueSpecification<number>): this;
    /** Set `fill-antialias` paint property on one or more layers. */
    setFillAntialias(value: PropertyValueSpecificationEx<boolean>): this;
    /** Set `fill-opacity` paint property on one or more layers. */
    setFillOpacity(value: DataDrivenPropertyValueSpecification<number>): this;
    /** Set `fill-color` paint property on one or more layers. */
    setFillColor(value: DataDrivenPropertyValueSpecification<ColorSpecification>): this;
    /** Set `fill-outline-color` paint property on one or more layers.*/
    setFillOutlineColor(value: DataDrivenPropertyValueSpecification<ColorSpecification>): this;
    /** Set `fill-translate` paint property on one or more layers. */
    setFillTranslate(value: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>): this;
    /** Set `fill-translate-anchor` paint property on one or more layers. */
    setFillTranslateAnchor(value: PropertyValueSpecificationEx<"map" | "viewport">): this;
    /** Set `fill-pattern` paint property on one or more layers. */
    setFillPattern(value: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>): this;
    /** Get `fill-sort-key` layout property of layer. */
    getFillSortKey(): DataDrivenPropertyValueSpecification<number>;
    /** Get `fill-antialias` paint property of layer. */
    getFillAntialias(): PropertyValueSpecificationEx<boolean>;
    /** Get `fill-opacity` paint property of layer. */
    getFillOpacity(): DataDrivenPropertyValueSpecification<number>;
    /** Get `fill-color` paint property of layer. */
    getFillColor(): DataDrivenPropertyValueSpecification<ColorSpecification>;
    /** Get `fill-outline-color` paint property of layer. */
    getFillOutlineColor(): DataDrivenPropertyValueSpecification<ColorSpecification>;
    /** Get `fill-translate` paint property of layer. */
    getFillTranslate(): PropertyValueSpecificationEx<[number, number]>;
    /** Get `fill-translate-anchor` paint property of layer. */
    getFillTranslateAnchor(): PropertyValueSpecificationEx<"map" | "viewport">;
    /** Get `fill-pattern` paint property of layer. */
    getFillPattern(): DataDrivenPropertyValueSpecification<ResolvedImageSpecification>;
}


export  class OverlayLayerBase {
    sourceId?: string;
    layerId?: string;
    _map?: Map;
    constructor();
    addTo(map: Map, beforeId?: string): void;
    /**
     * Get data source ID
     * @return {string | undefined}
     */
    getSourceId(): string | undefined;
    /**
     * Get layer ID
     * @return {string | undefined}
     */
    getLayerId(): string | undefined;
    /**
     * Get data source data
     * @return {GeoJsonGeomertry | undefined}
     */
    getData(): GeoJsonGeomertry | undefined;
    remove(): void;
    /** Set map cursor to "pointer" when mouse hovers over these layers.
     @returns A function to remove the handler.
     * @param layerOrLayers
     */
    hoverPointer(): void;
    /**
     Update feature state in connected source when mouse hovers over a feature in these layers.
     * @param enterCb
     * @param leaveCb
     */
    hoverFeatureState(enterCb?: (arg0: {}) => void, leaveCb?: (arg0: {}) => void): void;
    /** Show a popup when mouse hovers over a feature in these layers.
     @param htmlFunc Function that receives feature and popup, returns HTML.
     @param {Object<PopupOptions>} popupOptions Options passed to `Popup()` to customise popup.
     @example hoverPopup(f => `<h3>${f.properties.Name}</h3> ${f.properties.Description}`, { anchor: 'left' });
     */
    hoverPopup(htmlFunc: any, popupOptions?: PopupOptions): any;
    /** Show a popup when clicking a feature in these layers.
     @param htmlFunc Function that receives feature and popup, returns HTML.
     @param {Object<PopupOptions>} popupOptions Options passed to `Popup()` to customise popup.

     @returns A function that removes the handler.
     @example clickPopup(f => `<h3>${f.properties.Name}</h3> ${f.properties.Description}`, { maxWidth: 500 });

     */
    clickPopup(htmlFunc: (arg0: {}) => void, popupOptions?: PopupOptions): any;
    /** Trigger callback when clicking a feature in these layers.
     @param {function} cb Callback that receives event with .features property
     @returns A function that removes the handler.
     */
    clickLayer(cb: any): any;
    /** Trigger callback when mouse hovers over a feature in these layers.
     @returns A function to remove the handler.
     */
    hoverLayer(cb: any): any;
    /**
     * Make the given layer visible.
     * @param layer
     */
    show(): void;
    /**
     * Make the given layer invisible.
     * @param layer
     */
    hide(): void;
    /** Hide or show the given layer based on parameter.
     @param {boolean} state True for visible, false for hidden.
     */
    toggle(state: boolean): boolean;
    /** Set paint or layout property on one or more layers.
     @example setProperty('fillOpacity', 0.5)
     */
    setProperty(prop: string | object, value?: any): void;
    /** Get layer definition for given layer ID according to style spec.
     */
    getLayerStyle(): LayerSpecification;
    /**
     * Set layer style
     * @param layer
     * @param style
     */
    setLayerStyle(style: any): void;
    /** Replace the filter of a layer.
     @param {Array} filter New filter to set.
     @example setFilter(['==','level','0']]);
     */
    setFilter(filter: FilterSpecification): void;
}

export  interface OverlayLayerBaseOptions {
    sourceId?: string;
    sourceLayer?: string;
    layerId?: string;
    minzoom?: number;
    maxzoom?: number;
    filter?: any;
    visibility?: "visible" | "none";
    isHoverPointer?: boolean;
    isHoverFeatureState?: boolean;
}


export  type FillLayerSpecification = {
    id: string;
    type: "fill";
    metadata?: unknown;
    source: string;
    "source-layer"?: string;
    minzoom?: number;
    maxzoom?: number;
    filter?: FilterSpecification;
    layout?: {
        "fill-sort-key"?: DataDrivenPropertyValueSpecification<number>;
        visibility?: "visible" | "none";
    };
    paint?: {
        "fill-antialias"?: PropertyValueSpecificationEx<boolean>;
        "fill-opacity"?: DataDrivenPropertyValueSpecification<number>;
        "fill-color"?: DataDrivenPropertyValueSpecification<ColorSpecification>;
        "fill-outline-color"?: DataDrivenPropertyValueSpecification<ColorSpecification>;
        "fill-translate"?: PropertyValueSpecificationEx<[number, number]>;
        "fill-translate-anchor"?: PropertyValueSpecificationEx<"map" | "viewport">;
        "fill-pattern"?: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>;
    };
};

export  type FillLayerStyleProp = {
    metadata?: unknown;
    source?: string;
    sourceLayer?: string;
    minzoom?: number;
    maxzoom?: number;
    filter?: FilterSpecification;
    visibility?: "visible" | "none";
    fillSortKey?: DataDrivenPropertyValueSpecification<number>;
    fillAntialias?: PropertyValueSpecificationEx<boolean>;
    fillOpacity?: DataDrivenPropertyValueSpecification<number>;
    fillColor?: DataDrivenPropertyValueSpecification<ColorSpecification>;
    fillOutlineColor?: DataDrivenPropertyValueSpecification<ColorSpecification>;
    fillTranslate?: PropertyValueSpecificationEx<[number, number]>;
    fillTranslateAnchor?: PropertyValueSpecificationEx<"map" | "viewport">;
    fillPattern?: DataDrivenPropertyValueSpecification<ResolvedImageSpecification>;
};

export  type FilterSpecification = ["has", string] | ["!has", string] | ["==", string, string | number | boolean] | ["!=", string, string | number | boolean] | [">", string, string | number | boolean] | [">=", string, string | number | boolean] | ["<", string, string | number | boolean] | ["<=", string, string | number | boolean] | Array<string | FilterSpecification>;
