ol-dji-geozones
v2.3.0
Published
Displays DJI Geo Zones on an OpenLayers map.
Downloads
43
Maintainers
Readme
OpenLayers DjiGeozones
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.
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/[email protected]"></script>
CSS
<link rel="stylesheet" href="https://unpkg.com/[email protected]/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
opt_options
Options? DjiGeozones options, see DjiGeozones Options for more details.
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
map
Map
Returns void
setPanelVisible
Show or hides the control panel
Parameters
visible
boolean
Returns void
setPanelCollapsed
Collapse/expand the control panel
Parameters
collapsed
boolean
Returns void
layers
Get all the layers
Type: Array<VectorLayer<Feature>>
Returns Array<VectorLayer<Feature>>
getLayerByLevel
Get the layer acordding the level
Parameters
level
number
Returns VectorLayer<Feature>
drone
Setter for API parameter drone
. Triggers an API request
Type: string
Parameters
drone
string
drone
Getter for Api parameter drone
Type: string
Returns string
zonesMode
Setter for API parameter zonesMode
. Triggers an API request
Type: string
Parameters
zonesMode
string
zonesMode
Getter for API parameter zonesMode
Type: string
Returns string
country
Setter for API parameter country
. Triggers an API request
Type: string
Parameters
country
string
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, defaultnull
)
Returns Level
activeLevels
Replace the active levels with this values and refresh the view
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, defaulttrue
)
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, defaulttrue
)
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
error
Error
deepObjectAssign
Parameters
target
sources
...any
ApiReqArguments
[interface] - Dji Api Parameters for requests
level
0
- Warning Zones1
- Authorization Zones2
- Restricted Zones3
- Enhanced Warning Zones4
- Regulatory Restricted Zones5
- Recommended Zones (2) Apparently this level is only valid for Japan6
- Altitude Zones7
- Recommended Zones8
- Approved Zones for Light UAVs(China) Only valid for China9
- 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
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 Prophantom-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
US
AR
- etc (See the supported list)
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
activeLevels
Geozone Levels to be actived by default in the Control and API request
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
msg
string
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.