0

We are using Leaflet already on one of our site but now we are migrating to Angular. Now we are trying to reproduce it using Ngx-Leaflet.

But we don't have the country borders...

What we have right now:

In the component.html

    <div class="col col-md-8">
    <div style="height: 700px; padding: 0; width: 100%;" leaflet [(leafletZoom)]="leafletZoom"
        [(leafletCenter)]="leafletCenter" [leafletMaxZoom]="leafletMaxZoom" [leafletMinZoom]="leafletMinZoom"
        [leafletOptions]="leafletOptions"
        [leafletLayers]="leafletLayers">
    </div>
</div>

In the component.ts in the ngOnInit()

        this.leafletZoom = 4;
    this.leafletMaxZoom = 4;
    this.leafletMinZoom = 4;
    this.leafletCenter = latLng([this.lat, this.lng]);

    this.geoJSONsOption = { style: { 'color': '#ff7800', 'weight': 5, 'opacity': 0.65 } };
    this.projectMapJsonService.getProjectMapJson().subscribe((data: any) => {
        this.geoJSONs = data;
        // console.log(this.geoJSONs);
        let defaultBaseLayer = tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; OpenStreetMap contributors'
        });
        let defaultOverlay = geoJSON(this.geoJSONs, this.geoJSONsOption);
        this.leafletLayers = [
            defaultBaseLayer,
            defaultOverlay
        ];
    });

    this.leafletOptions = {};

The GeoJson is like

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"Afghanistan","iso":"AF","label":"1","totalentries":"430","show_on_map":true},"geometry":{"type":"Point","coordinates":["65","33"]}},...

I have difficulties finding how to convert some of the code E.g.

            var countries_options = {
            insets: true,
            style: {
                fillColor: getColor(feature.properties.label),
                weight: 2,
                opacity: 1,
                color: 'white',
                dashArray: '3',
                fillOpacity: 0.7,
                visible: false
            },

            onEachFeature: function (feature2, layer) {

                layer.on({
                    mouseover: function (e) {
                        info.update(feature.properties);
                    },
                    mousemove: function (e) {

                        var popup = L.popup({
                                offset: new L.Point(120, 0),
                                closeButton: false,
                                className: 'popuphomemap'
                            })
                            .setLatLng(e.latlng)
                            .setContent('Click to have the list of the projects')
                            .openOn(homeMap);
                    },

                    mouseout: function () {
                        info.update();
                    },
                    click: function () {
                        info.click(feature.properties);
                    }
                });
            }
        }
L.wt.countries([{
            "level": 0,
            "countries": [cca2]
        }], countries_options).addTo(homeMap);

I would be grateful if somebody can support me or share code with such features.

NgxLeaflet rendering

Workingview using Leaflet

kboul
  • 13,836
  • 5
  • 42
  • 53
Jean-Philippe M
  • 731
  • 1
  • 7
  • 19
  • I have moved through another solution right now following this tutorial: https://alligator.io/angular/angular-and-leaflet-shape-service/. But I am still willing to go further with ngx-leaflet – Jean-Philippe M Nov 29 '19 at 12:15
  • What exactly do you want to achieve cause you have two different pics? You want to highlight each European country on hover using ngx-leaflet? – kboul Nov 29 '19 at 13:22
  • @kboul exactly, I want to reproduce the same with the countries highlighted with a gradient Color related to an assigned value – Jean-Philippe M Nov 30 '19 at 20:12
  • Hello. Did you check my answer? Does it answer your question? – kboul Dec 04 '19 at 10:10

2 Answers2

3

Here is an example of highlighting European countries using ngx-leaflet that have have different colours depending on the country population.

Get the map reference using onMapReady and then do everything as you would do on vanilla js inside that method. I used a json with the european countries from here.

onMapReady(map: L.Map) {
    function resetHighlight(e) {
      geojson.resetStyle(e.target);
    }

    function getColor(d) {
      return d > 100000000
        ? "#800026"
        : d > 80000000
        ? "#BD0026"
        : d > 50000000
        ? "#E31A1C"
        : d > 10000000
        ? "#FC4E2A"
        : d > 1000000
        ? "#FD8D3C"
        : d > 1000000
        ? "#FEB24C"
        : d > 100000
        ? "#FED976"
        : "blue";
    }

    function style(feature) {
      return {
        weight: 2,
        opacity: 1,
        color: "white",
        dashArray: "3",
        fillOpacity: 0.7,
        fillColor: getColor(feature.properties.pop_est)
      };
    }

    function highlightFeature(e) {
      var layer = e.target;

      layer.setStyle({
        weight: 5,
        color: "#666",
        dashArray: "",
        fillOpacity: 0.7
      });

      if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
        layer.bringToFront();
      }
    }

    const onEachFeature = (feature, layer) => {
      layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight
      });
    };

    let geojson = L.geoJSON(euCountries, {
      style: style,
      onEachFeature: onEachFeature
    }).addTo(map);

    map.fitBounds(geojson.getBounds());
  }

You can see the ful lexample here

Based on that you can add any additional functionality you wish.

kboul
  • 13,836
  • 5
  • 42
  • 53
0
    import { AfterViewInit, Component } from '@angular/core';
import * as L from 'leaflet';
import { MapService } from './map.service';
import { OutlinecountriesService } from './outlinecountries.service';

@Component({
    selector: 'app-map',
    templateUrl: './map.component.html',
    // styleUrls: ['./map.component.scss']
})
export class MapComponent implements AfterViewInit {
    private map: L.Map;
    private countries: any;

    constructor(private mapService: MapService, private outlinecountriesService: OutlinecountriesService) { }

    ngAfterViewInit(): void {
        this.initMap();
        this.mapService.makeMarkers(this.map);
        this.outlinecountriesService.getCountriesShapes().subscribe(countries => {
            this.countries = countries;
            this.initCountriesLayer();
        });
    }

    private initMap(): void {
        this.map = L.map('map', {
            center: [50.8503, 4.3517],
            zoom: 3
        });

        const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        });

        tiles.addTo(this.map);
    }

    private initCountriesLayer() {
        // console.log(this.countries);
        const countriesLayer = L.geoJSON(this.countries, {
            style: (feature) => ({
                weight: 3,
                opacity: 0.5,
                color: '#008f68',
                fillOpacity: 0.5,
                fillColor: this.getColor(feature.properties.label, feature.properties.totalentries)
            }),
            onEachFeature: (feature, layer) => (
                layer.on({
                    mouseover: (e) => (this.highlightFeature(e)),
                    mouseout: (e) => countriesLayer.resetStyle(e.target),
                })
            )
        });

        this.map.addLayer(countriesLayer);
    }

    private highlightFeature(e: any) {
        const layer = e.target;
        layer.setStyle({
            weight: 3,
            opacity: 0.5,
            color: '#DFA612',
            fillOpacity: 1.0,
            fillColor: '#FAE042',
        });
    }

    private getColor(value: any, maxValue: any) {
        // console.log(value);
        // console.log(maxValue);

        return value > maxValue
            ? '#800026'
            : value > maxValue * (90 / 100)
                ? '#BD0026'
                : value > maxValue * (80 / 100)
                    ? '#E31A1C'
                    : value > maxValue * (70 / 100)
                        ? '#FC4E2A'
                        : value > maxValue * (60 / 100)
                            ? '#FD8D3C'
                            : value > maxValue * (50 / 100)
                                ? '#FEB24C'
                                : value > maxValue * (40 / 100)
                                    ? '#FED976'
                                    : 'blue';
    }

}
Jean-Philippe M
  • 731
  • 1
  • 7
  • 19