Giter Site home page Giter Site logo

wykks / ngx-mapbox-gl Goto Github PK

View Code? Open in Web Editor NEW
340.0 16.0 129.0 26.04 MB

Angular binding of mapbox-gl-js

Home Page: https://wykks.github.io/ngx-mapbox-gl

License: MIT License

TypeScript 97.93% JavaScript 0.25% HTML 0.93% CSS 0.47% Shell 0.11% SCSS 0.32%
angular mapbox-gl

ngx-mapbox-gl's Introduction

ngx-mapbox-gl

npm version

Angular wrapper for mapbox-gl-js. It exposes a bunch of components meant to be simple to use with Angular.

v1.X : Angular 5 & 6 (rxjs 5)

v2.X : Angular 6 & 7 (rxjs 6)

v3.X : Angular 7.2

v4.X : Angular 8 - 10 (rxjs >= 6.5)

v5.X - 6.X : Angular 9 - 11 (rxjs >= 6.5)

v7.X : Angular 12 (rxjs >= 6.6)

v8.X : Angular 13

v9.X : Angular 14

v10.X : Angular 16

Include the following components:

(Documentation here: https://wykks.github.io/ngx-mapbox-gl/doc)

How to start

npm install ngx-mapbox-gl mapbox-gl
yarn add ngx-mapbox-gl mapbox-gl

If using typescript add mapbox-gl types

npm install @types/mapbox-gl --save-dev
yarn add @types/mapbox-gl --dev

Load the CSS of mapbox-gl

For example, with angular-cli add this in angular.json:

"styles": [
        ...
        "mapbox-gl/dist/mapbox-gl.css"
      ],

Or in the global CSS file (called styles.css for example in angular-cli):

@import '~mapbox-gl/dist/mapbox-gl.css';

Then, in your app's main module (or in any other module), import the NgxMapboxGLModule:

...
import { NgxMapboxGLModule } from 'ngx-mapbox-gl';

@NgModule({
  imports: [
    ...
    NgxMapboxGLModule.withConfig({
      accessToken: 'TOKEN', // Optional, can also be set per map (accessToken input of mgl-map)
    })
  ]
})
export class AppModule {}

How to get a Mapbox token: https://www.mapbox.com/help/how-access-tokens-work/

Note: mapbox-gl cannot work without a token anymore. If you want to keep using their services then make a free account, generate a new token for your application and use it inside your project.

Display a map:

import { Component } from '@angular/core';

@Component({
  template: `
    <mgl-map
      [style]="'mapbox://styles/mapbox/streets-v9'"
      [zoom]="[9]"
      [center]="[-74.5, 40]"
    >
    </mgl-map>
  `,
  styles: [
    `
      mgl-map {
        height: 100%;
        width: 100%;
      }
    `,
  ],
})
export class DisplayMapComponent {}

ngx-mapbox-gl's People

Contributors

babyrne avatar bergkamphun avatar bernhardrode avatar caiuscitiriga avatar dangrussell avatar dependabot[bot] avatar dhermyt avatar dkocich avatar dmytro-gokun avatar eimanip avatar eschricker avatar freakybytes avatar harellevy avatar ivaka avatar jdenbroeder avatar lennyz71 avatar mikgross avatar mloffer avatar neverwalk avatar nosfit avatar paullryan avatar raysuelzer avatar sandikbarr avatar sroettering avatar tamim-khan avatar ulflander avatar webberig avatar wheredoesyourmindgo avatar wykks avatar yaroslavkormushyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngx-mapbox-gl's Issues

Change Detection Issue with Map

I've tried to add ngx-mapbox-gl to a couple of projects of mine but I'm stuck on Change Detection Issues. It's been very difficult to debug cause I'm not getting any error messages in the console.

I've created a Stackblitz to demonstrate some areas of confusion. Basically, this app just toggle's an Angular Material Side-navigation component in and out on click. Different click events for the boilerplate on top and the mgl-map on the bottom.

My first question relates to line: 58 in app.component.ts Why do I need to detect for changes using Angular's ChangeDetectionRef in order for the sidenav to open and close?

weird issue with mgl-image / mgl-layer (layer-icons disappear)

Hey @Wykks using your awesome library again (working on a coffee for you) but came across a strange bug / behaviour.
I use one mgl-geojson-sourceand multiple mgl-layer that filter part of the data (f.e. [filter]="['all', ['!has', 'point_count'], ['==', 'Kategorie', 'Wanderung']]") and use an mgl-image as icon-image.

So far, so working good. But: every 10th load er so, only some of the layers render initially and only reappear from that on on some zoom-levels (oh and none of them are clickable, if that happens).

You can take a look at the app here: https://tdsn-2018.firebaseapp.com/ (just reload multiple times and suddenly only some of the markers will appear).

Any suggestion / idea / hint would be awesome.

GeoJSON namespace missing

after installing and add to app.module - multiple errors appear :'Cannot find namespace "GeoJSON"

Add [(ngModel)] for <mgl-control mglGeocoder>

Is there a way to specify the model for <mgl-control mglGeocoder>?

Scenario:

  1. User selects an address from a dialog.

dialogRef.afterClosed().subscribe(addr => {
this.geocoderInput = addr;
/* this.geocoder.query(addr); */
});


Template:
`<mgl-control mglGeocoder [(ngModel)]="geocoderInput">`

error in wiki

Hi there, me again...

Found another problem with the docs. I've never edited a github wiki before but it seems maybe I don't have privilege?

Anyway, your sample code here: https://github.com/Wykks/ngx-mapbox-gl/wiki/API-Documentation#example-1

source needs to be in square brackets (at least for me anyway) I was using a polygon.

...
<mgl-map
  ...
>
  <mgl-layer
    id="state-borders"
    type="line"
    [source]="states"
    [paint]="{
      'line-color': '#627BC1',
      'line-width': 2
    }"
  ></mgl-layer>
</mgl-map>

question: how to pass nested objects to <mgl-feature> "properties" input

as said, I'm trying to pass a nested Object
myObj = {id: 123, data: {name: 'foo', surname: 'bar'}}
to the mgl-feature [properties] input to be later able to populate a popup with that data. But unfortunately the object from second level on (myObj.data) gets stringified. Any ideas (or suggestions for different ways very welcome.

bug: changeing style messes up z-index with other layers

Hey,

when you change the mgl-map style and you have a layer with markers p.e. the markers get lost. I could bet that this is a z-index issue. I will try to find a bugfix.
You can reproduce the issue be adapting the "change a maps style" demo according to this:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'mgl-demo',
  template: `
  <mgl-map
    [style]="style"
    [zoom]="[13]"
    [center]="[-71.976080,-13.521338]"
  >
    <mgl-vector-source
      id="museums"
      url="mapbox://mapbox.2opop9hr"
    >
    </mgl-vector-source>

    <mgl-layer
      id="museums"
      type="circle"
      source="museums"
      [paint]="{
        'circle-radius': 8,
        'circle-color': 'rgba(55,148,179,1)'
      }"
      sourceLayer="museum-cusco"
    >
    </mgl-layer>
  </mgl-map>
  <mat-radio-group [ngModel]="layerId" (ngModelChange)="changeStyle($event)">

    <mat-radio-button value="basic">basic</mat-radio-button>
    <mat-radio-button value="streets">streets</mat-radio-button>
    <mat-radio-button value="bright">bright</mat-radio-button>
    <mat-radio-button value="light">light</mat-radio-button>
    <mat-radio-button value="dark">dark</mat-radio-button>
    <mat-radio-button value="satellite">satellite</mat-radio-button>
  </mat-radio-group>
  `,
  styleUrls: ['./examples.css', './set-style.component.css']
})
export class SetStyleComponent implements OnInit {
  layerId = 'basic';
  style: string;

  ngOnInit() {
    this.changeStyle(this.layerId);
  }

  changeStyle(layerId: string) {
    this.style = `mapbox://styles/mapbox/${layerId}-v9`;
  }
}

Provide example for using mgl-layer

On the API documentation for the mgl-marker component you write:

Note: Only use this if you really need to use HTML/Angular component to render your symbol. These markers are slow compared to a Layer of symbol because they're not rendered using WebGL.

Could you provide an example on how to accomplish this and maybe how to attach a popup to a marker created like this?

Thanks a lot for this library!

Uncaught Error: Cannot find module "mapbox-gl"

I am using ionic 3. I have installed module as mentioned in readme file.

I am getting error:
Uncaught Error: Cannot find module "mapbox-gl"
at Object.defineProperty.value (vendor.js:125364)
at webpack_require (bootstrap c6e261b75fefa3a6dcec:54)
at Object.241 (main.ts:5)
at webpack_require (bootstrap c6e261b75fefa3a6dcec:54)
at Object.227 (main.js:80)
at webpack_require (bootstrap c6e261b75fefa3a6dcec:54)
at webpackJsonpCallback (bootstrap c6e261b75fefa3a6dcec:25)
at main.js:1

Performance Question

@Wykks
I'm using this current WeatherImageryFeed. I'm curious about it's rendering performance. It's so slow. Is there a better way to retrieve it or could there be a bug in mapbox-gl?
Thanks

<mgl-raster-source
         id="radar"
         [tiles] = "['https://nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WmsServer?bbox={bbox-epsg-3857}&service=WMS&request=GetMap&version=1.3.0&layers=1&styles=&format=image/png&transparent=true&height=256&width=256&crs=EPSG:3857']"
         [tileSize] = "256">
       </mgl-raster-source>

Production Build Errors

When I load a page with a map on it, everything loads fine and the map shows up and you can do what you will with it. As soon as I leave the page and navigate to another page I get the below error.

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'remove' of undefined
TypeError: Cannot read property 'remove' of undefined
    at n.onRemove (mapbox-gl.js:33)
    at o.removeControl (mapbox-gl.js:33)
    at ngx-mapbox-gl.js:555
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138)
    at NgZone.push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular (core.js:3783)
    at MapService.push../node_modules/ngx-mapbox-gl/fesm5/ngx-mapbox-gl.js.MapService.removeControl (ngx-mapbox-gl.js:554)
    at ControlComponent.push../node_modules/ngx-mapbox-gl/fesm5/ngx-mapbox-gl.js.ControlComponent.ngOnDestroy (ngx-mapbox-gl.js:1222)
    at callProviderLifecycles (core.js:9573)
    at callElementProvidersLifecycles (core.js:9541)
    at n.onRemove (mapbox-gl.js:33)
    at o.removeControl (mapbox-gl.js:33)
    at ngx-mapbox-gl.js:555
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138)
    at NgZone.push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular (core.js:3783)
    at MapService.push../node_modules/ngx-mapbox-gl/fesm5/ngx-mapbox-gl.js.MapService.removeControl (ngx-mapbox-gl.js:554)
    at ControlComponent.push../node_modules/ngx-mapbox-gl/fesm5/ngx-mapbox-gl.js.ControlComponent.ngOnDestroy (ngx-mapbox-gl.js:1222)
    at callProviderLifecycles (core.js:9573)
    at callElementProvidersLifecycles (core.js:9541)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:3815)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1540)

package.json

{
  "name": "ncri-spa",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "dev": "ng build",
    "production": "ng build --configuration=production",
    "staging": "ng build --configuration=staging",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@amcharts/amcharts3-angular": "^1.5.0",
    "@angular/animations": "^6.0.0",
    "@angular/common": "^6.0.0",
    "@angular/compiler": "^6.0.0",
    "@angular/core": "^6.0.0",
    "@angular/forms": "^6.0.0",
    "@angular/http": "^6.0.0",
    "@angular/platform-browser": "^6.0.0",
    "@angular/platform-browser-dynamic": "^6.0.0",
    "@angular/router": "^6.0.0",
    "@aspnet/signalr": "^1.0.2",
    "@auth0/angular-jwt": "^2.0.0",
    "@mapbox/mapbox-gl-draw": "^1.0.9",
    "@mapbox/mapbox-gl-geocoder": "^2.3.0",
    "@mapbox/mapbox-gl-sync-move": "^0.2.0",
    "core-js": "^2.5.4",
    "jwt-decode": "^2.2.0",
    "mapbox-gl": "^0.47.0",
    "mapbox-gl-compare": "^0.2.0",
    "ngx-mapbox-gl": "^2.0.0",
    "primeng": "^6.1.0",
    "rxjs": "^6.0.0",
    "zone.js": "^0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.6.1",
    "@angular/cli": "~6.0.1",
    "@angular/compiler-cli": "^6.0.0",
    "@angular/language-service": "^6.0.0",
    "@types/jasmine": "~2.8.6",
    "@types/jasminewd2": "~2.0.3",
    "@types/jwt-decode": "^2.2.1",
    "@types/mapbox-gl": "^0.47.0",
    "@types/node": "~8.9.4",
    "codelyzer": "~4.2.1",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~1.7.1",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~1.4.2",
    "karma-jasmine": "~1.1.1",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.3.0",
    "ts-node": "~5.0.1",
    "tslint": "~5.9.1",
    "typescript": "~2.7.2"
  },
  "browser": {
    "fs": false,
    "path": false,
    "os": false
  }
}

app.module.ts

NgxMapboxGLModule.withConfig({
      // Can also be set per map (accessToken input of mgl-map)
      accessToken: 'my access token',
      // Optionnal, specify if different from the map access token, can also be set per mgl-geocoder (accessToken input of mgl-geocoder)
      // geocoderAccessToken: 'TOKEN'
    }),

map.component.html

<div style="width: 100%; height: 400px;">
    <mgl-map #mbmap [style]="'mapbox://styles/mapbox/satellite-v9?optimize=true'" [zoom]="[3]" [center]="[-113.517209517767,50.950570]"
        (load)="onLoad($event)" [attributionControl]="false">
        <mgl-control mglNavigation></mgl-control>
        <mgl-control mglFullscreen position="top-left"></mgl-control>
        <mgl-control mglGeolocate position="top-left"></mgl-control>
        <mgl-control mglScale unit="metric" position="bottom-right"></mgl-control>
        <mgl-control position="bottom-left">
            <div class='legend' [style.display]="max === 0 ? 'none' : 'block'">
                <h4>Legend</h4>
                <div class="legend-content">
                    <div [ngClass]="selectedGradient.class" class="legend-scale"></div>
                    <div class="legend-values">
                        <h5 *ngFor="let s of selectedGradient.colors; let i = index">{{(min + (i * ((max - min) / selectedGradient.colors.length))).toFixed(2)}}</h5>
                        <h5>{{max.toFixed(2)}}</h5>
                    </div>
                </div>
            </div>
        </mgl-control>
    </mgl-map>
</div>

map.component.ts

import { HttpClient } from '@angular/common/http';
import { AppService } from '../../app.service';
import { Component, OnInit, Input, Output, OnChanges, SimpleChanges, EventEmitter } from '@angular/core';
import { } from 'mapbox-gl';
import { SharedComponent } from '../shared.component';
import { Map } from 'mapbox-gl';

@Component({
  selector: 'app-mb-map',
  templateUrl: './mb-map.component.html',
  styleUrls: ['./mb-map.component.scss']
})
export class MbMapComponent extends SharedComponent implements OnInit, OnChanges {
  // demo's of things you can do
  // https://wykks.github.io/ngx-mapbox-gl/demo/edit/live-update-feature

  /**
   * THe layer id to remove and add to the map when changing data layers.
   */
  layerId: number;

  /**
   * The source id to remove and add to the map when changing data layers.
   */
  sourceId: number;

  /**
   * The mapbox map.
   */
  map: Map;

  /**
   * The max value of the dataset.
   */
  max: number;

  /**
   * The min value of the dataset.
   */
  min: number;

  /**
   * The color gradients to apply to the map data with class names for legend.
   */
  gradients: any[];

  /**
   * The selected gradient chosen to render.
   */
  selectedGradient: any;

  /**
   * The points passed from a parent component.
   */
  @Input('data') data: any;


  // test files
  testFile: string;



  constructor(public appService: AppService, public httpClient: HttpClient) {
    super(appService);
    this.busy = false;
    this.gradients = [
      { class: 'r2g', colors: ['rgba(238, 46, 47, 0.3)', 'rgba(254, 204, 47, 0.3)', 'rgba(40, 167, 69, 0.3)'] },
      { class: 'b2p', colors: ['rgba(22, 103, 225, 0.3)', 'rgba(98, 22, 225, 0.3)', 'rgba(225, 22, 213, 0.3)'] },
    ];
    this.selectedGradient = this.gradients[0];
    this.layerId = 0;
    this.sourceId = 0;
    this.min = 0;
    this.max = 0;
  }

  /**
   * Update map on changes
   * @param changes
   */
  ngOnChanges(changes: SimpleChanges): void {

    if (changes.data && changes.data.currentValue !== changes.data.previousValue) {
      if (this.data.points && this.data.points.features.length > 0) {

        // set the min and max for the legend
        this.min = this.data.min;
        this.max = this.data.max;

        // draw the marker on the map
        // this.drawMarker(this.data.marker, this.data.points.features[0].geometry.coordinates);

        // TODO: Add the layer name to the data that gets passed to the points as the layer id and source id instead of incrementing. 
        // Might be able to save multiple layers in the map once loaded
        // so we can hide or show them without reloading the data.
        // draw the geojson layer
        this.drawGeoJsonPoints(
          this.map,
          this.data.points,
          `sourceId-${this.sourceId}`,
          `layerId-${this.layerId}`,
          this.data.min,
          this.data.max,
          this.selectedGradient.colors
        );
      }
    }
  }

  ngOnInit() {
  }

  drawMarker(title: string, coordinates: number[]) {

    // check if marker exists
    const exists = this.map.getLayer('marker');

    // remove if it does
    if (exists) {
      this.map.removeLayer('marker');
    }

    // add new marker
    this.map.addLayer({
      'id': 'marker',
      'type': 'symbol',
      'source': {
        'type': 'geojson',
        'data': {
          'type': 'FeatureCollection',
          'features': [{
            'type': 'Feature',
            'geometry': {
              'type': 'Point',
              'coordinates': coordinates
            },
            'properties': {
              'title': title,
              'icon': 'monument'
            }
          }]
        }
      },
      'layout': {
        'icon-image': '{icon}-15',
        'text-field': '{title}',
        'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],
        'text-offset': [0, 0.6],
        'text-anchor': 'top'
      }
    });
  }

  /**
   * Add's a layer on the map load function.
   * @param map The map.
   */
  onLoad(map: Map) {
    this.map = map;
  }

  /**
   * Draw's a set of GeoJson points on the map.
   * @param map The map to draw on.
   * @param geojson The path to a GeoJson file or a string representing GeoJson data.
   * @param sourceId An arbitrary unique id that separates this layer from any other added layers.
   * @param min The minimum value of the data source.
   * @param max The maximum value of the data source.
   * @param rgbaGradient The color gradient to use.
   */
  drawGeoJsonPoints(map: Map, geojson: any, sourceId: string, layerId: string, min: number, max: number, rgbaGradient: string[]) {
    // check for existence of layer
    const layerExists = map.getLayer(layerId);

    // remove it if it does
    if (layerExists) {
      map.removeLayer(layerId);
      console.log(`Layer with id of ${layerId} exists. Removing ${layerId}.`);
    }

    // check if source exists
    const sourceExists = map.getSource(sourceId);

    // remove it if it does
    if (sourceExists) {
      map.removeSource(sourceId);
      console.log(`Source with id of ${sourceId} exists. Removing ${sourceId}.`);
    }

    // add a data source for the map data to load from
    console.log('Adding source to map...');
    map.addSource(sourceId, {
      type: 'geojson',
      data: geojson, // path to geojson file
      cluster: true, // enable clustering
      clusterMaxZoom: 6, // Max zoom to cluster points on
      // clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
    });

    // get zone ranges for paint gradient
    console.log('Calculating zone...');
    const zone = (max - min) / rgbaGradient.length;

    // calculate stop values for each color gradient
    console.log('Calculating stop values for gradients from zone...');
    const gradients = [];
    for (let i = 0; i < rgbaGradient.length; i++) {
      gradients.push(min + (i * zone));
      gradients.push(rgbaGradient[i]);
    }
    // declare paint object prior
    // add interpolate function
    // interpolation type
    // the function to retrieve the value to interpolate by
    // the list of gradients and their stop values
    console.log('Configuring paint interpolation...');
    const paint = {
      'circle-color': ['interpolate', ['linear'], ['get', 'value'], ...gradients]
    };

    console.log('Adding layer...');
    map.addLayer({
      id: layerId,
      type: 'circle',
      source: sourceId,
      // filter: ['has', 'value'], // checks for nulls, if any are present it doesn't draw anything at all
      paint: paint,
    });
    console.log('Map points loaded.');
  }
}

Any chance anyone else is experiencing this problem?

Errors when import MapService

I am using ngx-mapbox-gl:1.0.0-beta.5 and I can't import MapService to my component. If i write like this

import {MapService} from 'ngx-mapbox-gl/src/app/lib/map/map.service';

i have an error while compiling

Module not found: Error: Can't resolve 'ngx-mapbox-gl/src/app/lib/map/map.service' 

if i change import to

import {MapService} from 'ngx-mapbox-gl/bundles/ngx-mapbox-gl.umd.js';

Compiled successfully. But i have errors in browser console like

core.js:1440 ERROR Error: Uncaught (in promise): Error: Can't resolve all parameters for MyComponent:

I think that it is an error in ng-packagr or something with it's config. Because if i use your source files in my app everything is fine and work as expected.

Cannot find namespace 'GeoJSON'

Current bundle:

  "dependencies": {
    "@agm/core": "^1.0.0-beta.2",
    "@agm/snazzy-info-window": "^1.0.0-beta.2",
    "@angular/animations": "^5.0.0",
    "@angular/cdk": "^5.0.0-rc0",
    "@angular/common": "^5.0.0",
    "@angular/compiler": "^5.0.0",
    "@angular/core": "^5.0.0",
    "@angular/forms": "^5.0.0",
    "@angular/http": "^5.0.0",
    "@angular/material": "^ 5.0.0-rc0",
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "@ngrx/effects": "^4.1.1",
    "@ngrx/router-store": "^4.1.1",
    "@ngrx/store": "^4.1.1",
    "@ngrx/store-devtools": "^4.1.1",
    "@ngx-translate/core": "^8.0.0",
    "@ngx-translate/http-loader": "^2.0.0",
    "@swimlane/ngx-charts": "^6.1.0",
    "angular2-token": "^0.2.0-beta.12",
    "bootstrap": "^4.0.0-beta",
    "core-js": "^2.4.1",
    "d3": "^4.11.0",
    "express": "^4.15.3",
    "font-awesome": "^4.7.0",
    "hammerjs": "^2.0.8",
    "mapbox-gl": "^0.42.0",
    "ngrx-store-localstorage": "^0.2.1",
    "ngx-mapbox-gl": "^1.0.0-beta.1",
    "ngx-toastr": "^6.5.0",
    "primeng": "^5.0.0-rc.0",
    "rxjs": "^5.5.2",
    "snazzy-info-window": "^1.1.0",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "1.5.0",
    "@angular/compiler": "^5.0.0",
    "@angular/compiler-cli": "^5.0.0",
    "@angular/language-service": "^5.0.0",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.2.0",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.4.2"
  }
}

I get this when trying to use the module:

node_modules/ngx-mapbox-gl/src/app/lib/map/map.service.d.ts(49,25): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/marker/marker.component.d.ts(7,15): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/marker/marker.component.d.ts(7,31): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/feature.component.d.ts(3,69): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/feature.component.d.ts(3,85): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/feature.component.d.ts(6,15): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(10,12): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(10,28): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(10,54): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(10,80): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(25,25): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(25,41): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(26,28): error TS2503: Cannot find namespace 'GeoJSON'.
node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(26,44): error TS2503: Cannot find namespace 'GeoJSON'.```

idea: replace yarn with npm

What do you think of replacing yarn with npm.

npm is the standard node package manage and imho any library should use it by default :)

Memory leak possability

i have been working with a project involving loading a dashboard lazy loaded module which contains a map component.
expected behaviour is that once navigate to another modules or children components, the map component should gets destroyed, leaving nothing behind in memory.
what happens is that when you navigate back to the dashboard module, a new instance of the map component along with the map service get initiated causing a rise in memory usage overtime when you navigate through the app different pages, because the map component doesn't get destroyed or garbage collected, reducing performance significantly over time.

capture

i experienced this in Angular 5.2.2 using just mapbox-gl 0.46.0, and now when i tried using ngx-mapbox-gl i found the same behaviour.

a reproducing repo

Error while building with latest angular and mapbox

The latest build seems to have an outdated GeoJSON implementation as I'm getting the following when building today:

ERROR in node_modules/ngx-mapbox-gl/src/app/lib/source/geojson/geojson-source.component.d.ts(6,22): error TS2420: Class 'GeoJSONSourceComponent' incorrectly implements interface 'GeoJSONSourceOptions'.
  Types of property 'data' are incompatible.
    Type 'string | Feature<GeometryObject, { [name: string]: any; }> | FeatureCollection<GeometryObject, { ...' is not assignable to type 'string | Feature<GeoJSONGeometry, { [name: string]: any; }> | FeatureCollection<GeoJSONGeometry, ...'.
      Type 'Feature<GeometryObject, { [name: string]: any; }>' is not assignable to type 'string | Feature<GeoJSONGeometry, { [name: string]: any; }> | FeatureCollection<GeoJSONGeometry, ...'.
        Type 'Feature<GeometryObject, { [name: string]: any; }>' is not assignable to type 'Feature<GeoJSONGeometry, { [name: string]: any; }>'.
          Type 'GeometryObject' is not assignable to type 'GeoJSONGeometry'.
            Type 'GeometryObject' is not assignable to type 'GeometryCollection'.
              Types of property 'type' are incompatible.
                Type 'GeoJsonGeometryTypes' is not assignable to type '"GeometryCollection"'.
                  Type '"Point"' is not assignable to type '"GeometryCollection"'.

I'm working on a PR to fix this.

Cluster on route transition

When you transition to a new route with 1.0.0.beta.3 and you have a cluster on a geoJSON source the current behavior is to remove the source with results in

mapbox-gl.js:546 Error: Source "properties" cannot be removed while layer "clusters" is using it.
    at t.removeSource (mapbox-gl.js:406)
    at e.removeSource (mapbox-gl.js:520)
    at ngx-mapbox-gl.js:470

If feels like you have fixed this with the new cluster mechanism for beta.4 + but I haven't been able to test it yet.

Global css

Hi,
How to add global css in ionic 3 application. Because in ionic 3 angular-cli.json in not available. Can you please help.

Regards and thanks
Khurshid Ansari

is it totally broken?

I just tried this several ways, precisely as described and with some tweaks, and the map simply never shows up. I get no console errors unless I try to put the map in the component and listen for onLoad in which case map is undefined and if I try to initialize it (map: Map = new Map()) then I get other errors.

app.module.ts:

import { NgxMapboxGLModule } from 'ngx-mapbox-gl';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    NgxMapboxGLModule.forRoot({
      accessToken: 'MY_TOKEN'
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html (also tried without the load event):

<mgl-map [style]="'mapbox://styles/mapbox/streets-v9'"
         [zoom]="9"
         [center]="[-74.50, 40]"
         (load)="map = $event"></mgl-map>

app.component.css (also tried with 100%):

mgl-map {
    height: 100vh;
    width: 100vw;
  }

app.component.ts (also tried with no map code):

map: Map;

 ngOnInit() {
   this.map.on('load', e => {
     console.log(e);
   });
 }

I was really hoping to use this in a big project. Seems like it would be super-useful. I'm hoping I am just missing something or some recent release just broke it temporarily?

bug? mgl-layer 'type' is required

The wiki doesn't explicit tells that it's required, but more so:

LayerComponent {
[...]
  @Input() type?: 'symbol ....'
}
  • the Input for type shouldn't be optional.

Tested with demo/geojson-line : removing type: "line" results in no line drawn.

Mapbox GL CSS missing

I was having an issue where the css was giving a 404, I was importing it as per the instructions:
@import "~mapbox-gl/dist/mapbox-gl.css";
The fix was to remove the .css from the end of the import statement.
@import "~mapbox-gl/dist/mapbox-gl";
I'm not sure if this is implementation specific (I am using Angular full-stack generator ), which uses SCSS/webpack/angular5. Or if this is simply an error in your documentation.

Ng content not working

base-map.html

<mgl-map #map[style]="'mapbox://styles/mapbox/streets-v9'"  [zoom]="[2]" [center]="[-103.59179687498357, 40.66995747013945]" (click)="onMapClick($event, map)"
  (load)="mapLoad($event)" (mouseMove)="onMapMouseMove($event, map)" [cursorStyle]="cursorStyle">
 
  <ng-content > </ng-content>

  <mgl-control mglGeocoder position="top-right"></mgl-control>
  
</mgl-map>

base-map.ts

import { Component,   } from '@angular/core';
import { MapMouseEvent } from 'mapbox-gl';

@Component({
  selector: 'base-map',
  templateUrl: 'base-map.component.html',
})

export class BaseMapComponent implements OnChanges {

  mapLoad() {  }
 
  onMapClick(evt: MapMouseEvent) {
    console.log(evt);
  }

  onMapMouseMove(evt: MapMouseEvent) {
    console.log(evt);
  }

}

point-map.html

<mgl-geojson-source id="mainSrc_cluster" [data]="mapGeoJSON" [cluster]="isCluster" [clusterMaxZoom]="14" [clusterRadius]="50">
    </mgl-geojson-source>
    <mgl-layer id="clusters" type="circle" source="mainSrc_cluster" [filter]="['has', 'point_count']" [paint]="{
          'circle-color': {
              property: 'point_count',
              type: 'interval',
              stops: [
                  [0, '#51bbd6'],
                  [100, '#f1f075'],
                  [750, '#f28cb1']
              ]
          },
          'circle-radius': {
              property: 'point_count',
              type: 'interval',
              stops: [
                  [0, 20],
                  [100, 30],
                  [750, 40]
              ]
          }
        }">
    </mgl-layer>

    <mgl-layer id="cluster-count" type="symbol" source="mainSrc_cluster" [filter]="['has', 'point_count']" [layout]="{
          'text-field': '{point_count}',
          'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
          'text-size': 12
        }">
    </mgl-layer>
    <mgl-layer id="unclustered-point" type="circle" source="mainSrc_cluster" (click)="onClick($event)" (mouseEnter)="cursorStyle = popupList.length > 0 || pointPopupHeader ? 'pointer' : ''"
      (mouseLeave)="cursorStyle = ''" [filter]="['!has', 'point_count']" [paint]="{
          'circle-color': unClusterPointColor,
          'circle-radius': [
            'interpolate', ['linear'], ['zoom'],
            10, 5,
            22, 20
          ],
          'circle-stroke-width': 1,
          'circle-stroke-color': '#fff'
        }">
    </mgl-layer>

similary i have file for lines.map.html, and have other files, containing layers and event handlers on that layer.

now in the main app file
main-app.ts

 <base-map #map>
            <point-map  [mapData]="mapData" [mapMetaData]="mapMetaData"
            [mapComponent]="map.mapComp" 
              ></point-map>
</base-map>

the problem with approach is that im getting error
ERROR Error: StaticInjectorError(AppModule)[LayerComponent -> MapService]:

also the element projected inside ng-content is called first in angular intitalization.
so layer, and geojson component is initialzed before mgl-map component

Layer with Canvas Source: The type property must be defined

I trying to make a canvas source work with a layer but it seem error always occur when I try to add the layer.

<canvas class="mycanvas" id="mycanvas" #mycanvas></canvas>
<mgl-map (load)="mapLoaded($event)" [style]="'mapbox://styles/mapbox/streets-v9'" [zoom]="[5]" [center]="[-75.789, 41.874]">
  <mgl-canvas-source id='canvasSource' #canvasSource [canvas]='mycanvas' [coordinates]="[
        [-81.490, 46.437],
        [-72.582, 46.437],
        [-72.582, 38.907],
        [-81.490, 38.907]
    ]"></mgl-canvas-source>
  <!-- add this line will occur error -->
  <mgl-layer id="canvasLayer" type="raster" [source]="canvasSource" [paint]="{'raster-opacity':0.85}"></mgl-layer>
</mgl-map>

suggestion: wiki update: mgl-feature inputs

The wiki says nothing aber mgl-featurecomponent. But being able to set properties is nice to know :)

## mgl-geojson-source [Mapbox GL style spec](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson)

[...]

### Inputs
#### mgl-geojson-source           <-
Init only:
* **id**: `string` _(Required)_

Dynamic:
* [**data**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-data): `GeoJSON.Feature | GeoJSON.FeatureCollection | string`
* [**maxzoom**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-maxzoom): `number`
* [**buffer**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-buffer): `number`
* [**tolerance**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-tolerance): `number`
* [**cluster**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-cluster): `boolean`
* [**clusterRadius**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-clusterRadius): `number`
* [**clusterMaxZoom**](https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-clusterMaxZoom): `number`

#### mgl-feature           <-
Init only:
* **geometry**: `GeoJSON.GeometryObject` _(Required)_
* **properties**: `any`

Dynamic:
* **id**: `number`

setting `[center]` on map affects zoom & vice versa

Dynamically changing this.center when

<mgl-map
...
    [center]="center"
    [zoom[="zoom"
...

resets the zoom to inital value - same the other way round.
(can be seen in demo: examples/center-on-symbol.component)

Expected behaviour:
Changing center/zoom shouldn't affect the zoom/center

map pin bound to dynamic coordinates is not updating its position

The title describes fairly accurately what I'm experiencing. I would like to be able to click on a map and have a map marker move to that location.

Here's my template:

	<mgl-map class=""
		[style]="'mapbox://styles/mapbox/streets-v9'"
		[zoom]="[9]"
		[center]="[153.021072, -27.470125]"
		(click)="mapClick($event)"
		>
		<mgl-marker
  			[feature]="pickerLocation"
		>
	  		<div
				(click)="alert('Foo')"
				class="marker"
	  		>
				<i class="fa fa-map-marker"></i>
				{{pickerLocation.geometry.coordinates}}
	  		</div>
		</mgl-marker>
	</mgl-map>

Here's the important bits from my controller:

	pickerLocation = {
		type: "Feature",
		geometry: {
			type: "Point",
			coordinates: [153.021072, -27.470125]
		}
	};

	mapClick(event) {
		if(event.lngLat){
			this.pickerLocation.geometry.coordinates = event.lngLat;
		}
		console.log(this.pickerLocation);
	}

When I click on the map the object coordinates property is being updated, this can be confirmed by seeing the template binding {{pickerLocation.geometry.coordinates}} updating, however the markers position isn't changing at all.

I've tried replacing the mgl-marker data source to a plain array or object, instead of a Feature. However this is having the same effect (the pin doesn't move on click).

how far is this project / which features are ready?

Hey, thanks for your great work!
Just tried and f.e. trackResize seems to do nothing and I couldn't get mgl-geojson-source to work either :(
A note in the wiki which features are done would be awesome!

getCurrentViewPortBox should not use canvas height / width, breaks supercluster

When changing the zoom level in the browser, the canvas height / width no longer accurately describes the accurate viewport box of what objects should be visible.

See: https://github.com/stepankuzmin/mapbox-gl-js/blob/master/src/ui/map.js#L1523

The result of this is that when markers or clusters are added to the maps, if the user changes the zoom level of the browser, then markers disappear from the map when they should still be visible.

For example, go to the demo here:
https://wykks.github.io/ngx-mapbox-gl/demo/ngx-marker-cluster
and set the zoom on the browser to 50%, you will see half the of the clusters completely disappear.

In order to get an accurate representation of the viewport box, the style property should be used to get the viewport box.

https://github.com/Wykks/ngx-mapbox-gl/blob/master/projects/ngx-mapbox-gl/src/lib/map/map.service.ts#L476-L477

Prod build Broken Cli 6.0.0-6.0.8

I have a Shared Module which imports NgxMapboxGLModule without calling forRoot.

The cli builds this package correctly with the --prod flag.

The app module which uses this shared module imports NgxMapboxGLModule.forRoot(). During production build using

ng build --prod

The following error is displayed:

ERROR in ./node_modules/@sharedmodule/shared/sharedmodule-shared.ngfactory.js Module not found: Error: Can't resolve './node_modules/ngx-mapbox-gl/ngx-mapbox-gl.ngfactory' in 'c:\TFS\DataLayers\UI\node_modules\@sharedmodule\shared'

Any idea what could be causing this, or is version 1.2.0 not ready for optimization with Cli version 6+?

Any idea if cli 6.1 beta would work?

Clusters - Marker options

I'm trying to use the <mgl-marker-cluster> and set the markers in it with anchor and offset options. Is this posible?

Upgrade to angular 6 and rxjs 6

After upgrade to angular 6:
ERROR in node_modules/ngx-mapbox-gl/app/lib/map/map.service.d.ts(5,10): error TS2305: Module '".... /node_modules/rxjs/Observable"' has no exported member 'Observable'

bug:<mgl-geojson-source> error when routing away before map has loaded

Reproduce:

  • add a <mgl-geojson-source id="symbols-source"></mgl-geojson-source> to a map (doesn't madder if w or w/o <mgl-feature>.
  • rout away from page with map before map has fully loaded.
  • Error:
Error: Uncaught (in promise): TypeError: Cannot read property 'unsubscribe' of undefined
TypeError: Cannot read property 'unsubscribe' of undefined
    at GeoJSONSourceComponent.ngOnDestroy (geojson-source.component.ts:79)

Display 3D buildings + How to handle events

I attempting to load 3D buildings using the source provide at mapbox 3D buildings . However, I don't see api documentation on how to pass an event to the map component via ngx-mapbox-gl. Is this possible? Looking over a few examples, I notice that load is being used, but it isn't explicitly clear, to me, how it functions.

Taken from language switch component

 <mgl-map
    style="mapbox://styles/mapbox/light-v9"
    [zoom]="[2.9]"
    [center]="[16.05, 48]"
    (load)="map = $event"
  >

Any input would be appreciated.

When using hostname and changing route: TypeError: Cannot read property 'remove' of undefined

When using localhost as the hostname, and navigating to another route, everything works fine and the map destroys itself.

When using the hostname though, when navigating to a new route, this error is thrown:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'remove' of undefined TypeError: Cannot read property 'remove' of undefined at i.onRemove (mapbox-gl.js:32) at n.removeControl (mapbox-gl.js:32) at ngx-mapbox-gl.js:255 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138) at NgZone.push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular (core.js:4021) at MapService.push../node_modules/ngx-mapbox-gl/esm5/ngx-mapbox-gl.js.MapService.removeControl (ngx-mapbox-gl.js:254) at ControlComponent.push../node_modules/ngx-mapbox-gl/esm5/ngx-mapbox-gl.js.ControlComponent.ngOnDestroy (ngx-mapbox-gl.js:667) at callProviderLifecycles (core.js:10420) at callElementProvidersLifecycles (core.js:10388) at i.onRemove (mapbox-gl.js:32) at n.removeControl (mapbox-gl.js:32) at ngx-mapbox-gl.js:255 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138) at NgZone.push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular (core.js:4021) at MapService.push../node_modules/ngx-mapbox-gl/esm5/ngx-mapbox-gl.js.MapService.removeControl (ngx-mapbox-gl.js:254) at ControlComponent.push../node_modules/ngx-mapbox-gl/esm5/ngx-mapbox-gl.js.ControlComponent.ngOnDestroy (ngx-mapbox-gl.js:667) at callProviderLifecycles (core.js:10420) at callElementProvidersLifecycles (core.js:10388) at resolvePromise (zone.js:814) at resolvePromise (zone.js:771) at zone.js:873 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421) at Object.onInvokeTask (core.js:4053) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188) at drainMicroTaskQueue (zone.js:595) at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500) at invokeTask (zone.js:1540)

I've tested with both IIS and http-server with the same results. Any idea how to get this to work?

map is not displaying

Hello,

I'm in a project with Angular 6 and I'm using the library but the map is not displaying and it does not give any errors, is anyone else going through this?

Am I importing it the wrong way?

All I see is:

WARNING: sanitizing unsafe style value mapbox://styles/mapbox/dark-v9 (see http://g.co/ng/security#xss).

Dom in devtools shows nothing for mgl-map

popup [lngLat] binding removes and adds marker causing close events to fire unnecessarily

Hi, first of all thanks for great library!

I noticed that I get some unwanted events fired for the popup (close) event. I believe that is because you are removing and adding the popup again to the map with the updated lnglat value. Could it be possible to use the underlying popup's setLngLat function instead? this should also update the map without firing the close events, I believe.

On a second note, have you considered adding mapbox gl draw library bindings? I might be able to help with that as well as I'm doing something with the draw library right now.

fitBounds of layer

First of all, thanks for the library, it made my day!

I need to update a geojson layer and fit it's bounds, when new data arrived.

Do you think there is a simple way to achieve this?

Angular Universal (SSR) support

I've taken a stab at this a couple of times and at the moment it appears to be mapbox dependent. The best way I found was to not use the typescript helpers for mapbox code and instead just require it after a isPlatformBrowser test but this is contrived.

I'm not expecting this to be an easy fix but a placeholder here for discussion seems appropriate.

I have an app that I am doing server side rendering using this library but I have to instantiate a jsdom instance and put it in place for global.window and global.Blob which is squirrely as a number of library check that window or window.document are non-existent to enable their server side code paths.

Add feature input to mgl-popup

It's a common use case to pass geometry.coordinates as lngLat input.
But when we want to re-open a popup, we need to change the ref of geometry.coordinates, not just the ref of the feature. It would be better to be able to pass the feature directly (just like it's done in mgl-marker)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.