Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ol-dji-geozones

GastonZalba83MIT2.3.0TypeScript support: included

Displays DJI Geo Zones on an OpenLayers map.

ol, openlayers, dji, uav, vant, drone, geozone, geo zones, flyzafe, airports, aerodrome, airspace, mavic, phantom 4

readme

OpenLayers DjiGeozones

npm version npm license

Displays DJI Geo Zones on an OpenLayers map. Also, you can add a Control Panel with map legends and selectors to change the drone and the levels to be shown.

The data is obtained directly from an undocumented DJI API. The official DJI Fly Safe Geo Zone Map that use the same data can be found here, and more information here.

Tested with OpenLayers version 5, 6, 7, 8 and 9.

DISCLAIMER

Nowadays, DJI doesn't offer any API documentation, so future support and access to the data is uncertain. Furthermore, the API endpoint has CORS restrictions and the header Content-Security-Policy: frame-ancestors 'self' http://*.dji.com https://*.dji.com, so all browsers requests must be proxied.

Light mode Dark mode

Examples

All the examples are configured using a free Proxy. If you notice some lag or slow performance, try one of your own.

  • Basic usage: create an OpenLayers map instance, and pass that map and options to the DjiGeozones constructor.

Usage

// Default options
let opt_options = {
    urlProxy: '',
    buffer: 10000, // to increase search zone (in meters)
    drone: 'spark', // See drone parameter in the DJI API section
    zonesMode: 'total', // See drone parameter in the DJI API section
    country: 'US', // See country parameter in the DJI API section
    showGeozoneIcons: true, // Display geozones icons
    displayLevels: [2, 6, 1, 0, 3, 4, 7], // Order is kept in the Control Panel
    activeLevels: [2, 6, 1, 0, 3, 4, 7],
    createPanel: 'full', // Create or not the control
    targetPanel: null, // Specify a target if you want the control to be rendered outside of the map's viewport.
    startCollapsed: false,
    startActive: true,
    dronesToDisplay: [], // By default, an array with all the drones
    extent: null,
    loadingElement:
        '<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>',
    clickEvent: 'singleclick',
    language: 'en',
    i18n: {}, // Create customized languages/texts. See i18n folder
    alert: null
};

// SETTING A REVERSE PROXY TO AVOID CORS
// For testing, you can run `chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security` to
// launch a Google Chrome instance with CORS disabled.
// This example uses allOrigins (https://github.com/gnuns/allOrigins), a free and open source javascript proxy.
// For production, deploy a custom instance or use yor own proxy.
opt_options.urlProxy = 'https://api.allorigins.win/raw?url=';

const djiGeozones = new DjiGeozones(opt_options);

map.addControl(djiGeozones); // or djiGeozones.setMap(map)

Methods

// Instance methods
// This methods clean the loaded features and fires a new API request.
djiGeozones.drone = 'spark';
djiGeozones.country = 'US'; // At the moment, this doesn't seem to affect the api response
djiGeozones.zonesMode = 'total';

djiGeozones.activeLevels = [1, 2, 3, 4, 6, 7]; // Set custom level values
djiGeozones.addLevels(5);
djiGeozones.removeLevels(7);

djiGeozones.setPanelVisible(true); // Show/hide the control panel
djiGeozones.setPanelCollapsed(true); // Collapse/expand the control panel

djiGeozones.hide(); // Hide the GeoZones and the map Control
djiGeozones.show(); // Show the GeoZones and the map Control

let layers = djiGeozones.layers; // array of ol/layer/Vector~VectorLayer instances
let layer = djiGeozones.getLayerByLevel(7); // returns an ol/layer/Vector~VectorLayer instance with the specefic level

Events

djiGeozones.once(`init`, () => console.log('Library is loaded'));
djiGeozones.on(`error`, () => console.log('An error ocurred'));

DJI API - What we know

Some considerations

  • The API doesn't accepts requests in large zoom levels (<9) aka search_radius, so the Geozones in the map are disabled in these zoom scales to manage this beahaivor.

  • The data returned by the API has some problems/strange behaviors:

    • The elements in level 6 (Altitude Zones, grey color) are returning from the api with level 2 in the properties (Restricted Zones, red color), and the elements in level 4 (Regulatory Restricted Zones, light blue color) with level 7 (Recommended Zones, green color). This makes very messy the frontend, and make it impossible to filter these levels accordingly in each request. To avoid this problem, this module functions completely different from the official map: performs the API requests including all levels, distributing the results in differents layers according to each level, and filtering that manipulating the layers visibility (not by the API request).
  • See DjiApi API for parameters and details.

Changelog

See CHANGELOG for details of changes in each release.

Install

Browser

JS

Load ol-dji-geozones.js after OpenLayers. Dji Geozones is available as DjiGeozones.

<script src="https://unpkg.com/ol-dji-geozones@2.3.0"></script>

CSS

<link rel="stylesheet" href="https://unpkg.com/ol-dji-geozones@2.3.0/dist/ol-dji-geozones.min.css" />

Parcel, Webpack, etc.

NPM package: ol-dji-geozones.

Install the package via npm

npm install ol-dji-geozones

JS

import DjiGeozones from 'ol-dji-geozones';

CSS

// css
import 'ol-dji-geozones/lib/css/ol-dji-geozones.css';
// or scss
import 'ol-dji-geozones/lib/scss/ol-dji-geozones.scss';
TypeScript type definition

TypeScript types are shipped with the project in the dist directory and should be automatically used in a TypeScript project. Interfaces are provided for DjiGeozones Options.

API

Table of Contents

DjiGeozones

Extends ol/control/Control~Control

OpenLayers Dji Geozones, creates multiples VectorLayers to display interactives DJI Geo Zones on the map, requesting the data on the fly to an DJI API.

Also, add a Control to select levels of interest and drone to filter the results.

Parameters

setMap

Remove the control from its current map and attach it to the new map. Pass null to just remove the control from the current map.

Parameters

Returns void

setPanelVisible

Show or hides the control panel

Parameters

Returns void

setPanelCollapsed

Collapse/expand the control panel

Parameters

Returns void

layers

Get all the layers

Type: Array<VectorLayer<Feature>>

Returns Array<VectorLayer<Feature>>

getLayerByLevel

Get the layer acordding the level

Parameters

Returns VectorLayer<Feature>

drone

Setter for API parameter drone. Triggers an API request

Type: string

Parameters

drone

Getter for Api parameter drone

Type: string

Returns string

zonesMode

Setter for API parameter zonesMode. Triggers an API request

Type: string

Parameters

zonesMode

Getter for API parameter zonesMode

Type: string

Returns string

country

Setter for API parameter country. Triggers an API request

Type: string

Parameters

country

Getter for API parameter country

Type: string

Returns string

getLevelById

Get all the parameters from a level and the i18n texts

Parameters
  • id number (optional, default null)

Returns Level

activeLevels

Replace the active levels with this values and refresh the view

Type: Array<number>

Parameters

addLevels

Add the level/s to the view

Parameters
  • levels (Array<number> | number)
  • refresh If true, refresh the view and show the active levels (optional, default true)

Returns void

removeLevels

Remove the level/s from the view

Parameters
  • levels (Array<number> | number)
  • refresh If true, refresh the view and show the actived levels (optional, default true)

Returns void

destroy

Removes the control, layers, overlays and events from the map

Returns void

hide

Hide the geoZones and the Control

Returns void

show

Show the geoZones and the Control

Returns void

ErrorEvent

Extends BaseEvent

Custom Event to pass error in the dispatchEvent

Parameters

deepObjectAssign

Parameters

  • target
  • sources ...any

ApiReqArguments

[interface] - Dji Api Parameters for requests

level

  • 0 - Warning Zones
  • 1 - Authorization Zones
  • 2 - Restricted Zones
  • 3 - Enhanced Warning Zones
  • 4 - Regulatory Restricted Zones
  • 5 - Recommended Zones (2) Apparently this level is only valid for Japan
  • 6 - Altitude Zones
  • 7 - Recommended Zones
  • 8 - Approved Zones for Light UAVs(China) Only valid for China
  • 9 - Densely Populated Area NOT SUPPORTED - This level exists in the oficial Geo Zone Map, but this data is not provided by the api. On the other hand, now days this level is apparently valid only for Japan and China

Type: Array<number>

drone

  • dji-mavic-3 (Mavic 3)
  • dji-mini-se (Mavic Mini SE)
  • dji-air-2s (Air 2s)
  • dji-fpv (FPV)
  • mavic-mini-2 (Mavic Mini 2)
  • mavic-mini (Mavic Mini)
  • mavic-2-enterprise (Mavic 2 Enterprise)
  • mavic-2 (Mavic 2)
  • mavic-air (Mavic Air)
  • mavic-air-2 (Mavic Air 2)
  • mavic-pro (Mavic Pro)
  • spark (Spark)
  • phantom-4-pro (Phantom 4 Pro)
  • phantom-4-advanced (Phantom 4 Advanced)
  • phantom-4 (Phantom 4)
  • phantom-4-rtk (Phantom 4 RTK)
  • phantom-4-multispectral (Phantom 4 Multispectral)
  • phantom-3-pro (Phantom 3 Pro
  • phantom-3-advanced (Phantom 3 Advanced)
  • phantom-3-standard (Phantom 3 Standard)
  • phantom-3-4K (Phantom 3 4K)
  • phantom-3-se (Phantom 3 SE)
  • inspire-2 (Inspire 2)
  • inspire-1-series (Inspire 1 Series)
  • m200-series (M200 Series)
  • m300-series (M300 Series)
  • m600-series (M600 Series)
  • m100 (M100)
  • mg1p (MG 1S/1A/1P/1P RTK/T10/T16/T20/T30)
  • dji-mini-2 (DJI Mini 2)

Type: string

country

Apparently doesn't affects the response of the api

Type: string

zones_mode

Apparently only accepts 'total'

Type: string

lng

Map View center point Longitude

Type: number

lat

Map View center point Latitude

Type: number

search_radius

Radius of the current view of the map

Type: number

i18n

[interface] - Custom Language specified when creating a DjiGeozones

Options

[interface] - DjiGeozones Options specified when creating a DjiGeozones instance

Default values:

{
  urlProxy: '',
  encodeURIRequest: true,
  buffer: 10000, // meters
  drone: 'spark', // See parameter in the DJI API section
  zonesMode: 'total', // See parameter in the DJI API section
  country: 'US', // See parameter in the DJI API section
  showGeozoneIcons: true, // Display geozones icons
  displayLevels: [2, 6, 1, 0, 3, 4, 7],
  activeLevels: [2, 6, 1, 0, 3, 4, 7],
  createPanel: 'full',
  targetPanel: null,
  startCollapsed: true,
  startActive: true,
  dronesToDisplay: null,
  extent: null,
  loadingElement: '<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>',
  clickEvent: 'singleclick',
  theme: 'light',
  language: 'en',
  i18n: {...} // Translations according to selected language
  alert: alert // Default browser alert function
}

urlProxy

Url/endpoint from a Reverse Proxy to avoid CORS restrictions

Type: string

encodeURIRequest

To encode or not the outgoing request (depending on proxy)

Type: boolean

buffer

Current map radius is increased by the provided value (in meters) and used to request the areas. Very useful for the highest zoom levels, to allow geozones near by being displayed. A value of 0 will only search geozones (the centroid of these) that are inside the current view extent.

Type: number

zonesMode

zonesMode to be used in the API request

Type: string

country

Country identifier to be used in the API request

Type: string

showGeozoneIcons

Display geozones icons

Type: boolean

displayLevels

Geozone Levels to be shown in the control panel

Type: Array<number>

activeLevels

Geozone Levels to be actived by default in the Control and API request

Type: Array<number>

dronesToDisplay

Use a custom drone list to show in the select. If not provided, we use all the available drones The models are extracted from https://flysafe-api.dji.com/dji/drones See drone for the complete list.

Type: Array<Drone>

extent

The bounding extent for layer rendering. The layers will not be rendered outside of this extent.

Type: Extent

createPanel

Create or not a control panel on the map

  • 'full' displays each level as a layer, with the possibility to activate or deactivate each one, color legends and a drone switcher.
  • 'compact' it's a simple toggler button to enable/disable the geoZones.
  • use false to disable the panel

Type: (boolean | "full" | "compact")

target

Specify a target if you want the control to be rendered outside of the map's viewport.

Type: (HTMLElement | string)

startCollapsed

Whether panel is minimized when created.

Type: boolean

startActive

Show GeoZones on initialize

Type: boolean

loadingElement

Loading element to be shown in the Controller when loading API data

Type: string

clickEvent

Type of Click event to activate the PopUp

Type: ("singleclick" | "dblclick")

theme

Color theme of the Control Panel

Type: ("light" | "dark")

language

Language to be used in the Controller panel and PopUp. This doesn't affects the API requests. If i18n is set, this will be ignored.

Type: ("en" | "es")

i18n

Add custom translations

Type: i18n

alert

Custom alert function to display messages

Parameters

Returns void

TODO

  • Add test to check inexpected changes on the API response.
  • Add customizable proxy function
  • Improve scss (add variables)
  • Add more events

License

MIT (c) Gastón Zalba.

changelog

Changelog

v1.0.0

  • Module created

v1.0.1

  • Added a js minified version, fixed some typos in readme and corrected definition file.

v1.0.2

  • Added a css minified version and fixed some examples.

v1.0.3

  • Added ES module version.

v1.0.4

  • Fixed attribute "files" inside package.json

v1.0.5

  • Extent property added dynamically to prevent strange bug in some occasions.

v1.0.6

  • Fixed package.json

v1.0.7

  • Fixed some bugs
  • Added methods to show or hide geoZones and the map Control

v1.0.8

  • Improved css

v1.0.9

  • Updated proxyUrl on examples and README
  • Added 'https://' to API url's to facilitate uses of proxys
  • Added 'full' and 'compact' panels versions.
  • Show the loading indicator also in collapsed mode.

v1.0.10

  • Added Visibility toggle

v1.0.11

  • Initialize layers and events only if it's visible. Otherwise, the initialization is deferred
  • Show alert when geoZones are forced to be displayed but the view is to large
  • Improved css in loading spinner

v1.0.12

  • Fixed loading spinner showing late

v1.0.13

  • Now a custom alert function can be used
  • Some refactoring to improve default values readibility

v1.0.14-15

  • Fixed minor bug within loading indicator

v1.0.16

  • Added new drones
  • Improved language support
  • Icon property crossOrigin setted to 'anonymous'

v1.0.17

  • Minor fixes, improved some comments

v1.0.18

  • Fixed bug when no opt_options are present
  • npm audt fix

v1.0.19

  • Improved typescript and rollup configuration
  • Added "watch" script
  • Updated dependencies
  • Added Source Maps

v2.0.0

  • Refactored code: class extends ol.control.Control (breaking changes)
  • Updated dependencies
  • Added new dji models
  • Converted css to scss
  • Removed unnecesary examples

v2.0.1

  • Ol7 compatibility
  • Updated CDNs in examples
  • Added new drones

v2.0.2

  • Fixed unnecesary request when the geozones are hidden and the map is dragged
  • Fix outdated terser with "overrides"

v2.1.0

  • Added "error" event
  • Added new drones
  • Removed "browser" attribute from package.json
  • Added "type" module attribute to package.json
  • Removed index.js
  • Updated dependencies

v2.1.1

  • Improved rollup and ts configs

v2.2.0

  • Added buffer option to increase the search area
  • Added ".js" extension on imports to work better with webpack 5 default's config
  • Lib is builded with es2017 target (downgraded from esnext)
  • Removed babel deps
  • Added header to dist files

v2.2.1

  • Improved error handling and listeners cleaning afterwards
  • Added type support to the customized ErrorEvent
  • Fixed potential bug displaying incorrect loading state
  • Added style pointer-events: none to control icon img
  • Added version on README examples urls

v2.2.2

  • Added new drones
  • Added attrbiute showGeozoneIcons to display/hide geozone icons
  • Fixed bug on geozones returning 99 as type in some drones
  • Minimal addition to the README
  • Updated to Ol8

v2.2.3

  • Updated dev dependencies and removed babel

v2.2.4

  • Added option encodeURIRequest

v2.3.0

  • Updated to Ol9 (types)
  • Updated drone list
  • Force css style in the drone select to be 100% width
  • Updated dependencies