import { Component, ViewChild, Input  } from '@angular/core';
import {MapService} from '../shared/leaflet/map.service';
import {GeocodingService} from "../shared/leaflet/geocoding.service";
import {Location} from "../shared/leaflet/core/location.class";
import { Http, Response, Headers } from '@angular/http';
import { OAuthService } from "angular-oauth2-oidc";
import { JobService } from "../shared/level.service";

@Component({
  selector: 'Maps',
  template: require<any>("./maps.component.html"),
  styles: [
        require<any>("./map.component.less")
    ],
  providers: [MapService, GeocodingService, JobService],
})
export class MapsComponent {

  public vtLayer: any=0;
  public enable: boolean = true;
  public map:any;
  public value: boolean = false;
  public wmsLayer: any;
  public URL:any;
  public layerName:any;


  constructor(private mapService: MapService, private geocoder: GeocodingService,private http: Http, private oauthService: OAuthService, private jobService: JobService) {}


  ngOnInit() {
       this.map = L.map("map", {
            zoomControl: false,
            center: L.latLng(40.731253, -73.996139),
            zoom: 12,
            minZoom: 4,
            maxZoom: 60,
            layers: [this.mapService.baseMaps.OpenStreetMap]
        });

    L.control.zoom({ position: "topright" }).addTo(this.map);
    L.control.scale().addTo(this.map);

    this.mapService.map = this.map;
    this.geocoder.getCurrentLocation()
        .subscribe(
            location => this.map.panTo([location.latitude, location.longitude]),
            err => console.error(err)
        );

    //list layers
    this.jobService.getLayers()
        .subscribe(result => {
            for(let i = 0; i< result.objects.length; i++){
                 this.vtLayer = result.objects;
            }
       });

  }

  addLayer(id){

    let data;

    console.log(id);

    if (typeof this.wmsLayer !== 'undefined'){
        this.map.removeLayer(this.wmsLayer);
        delete this.wmsLayer;
    }else{
    this.http.get('http://192.168.0.12/api/layers/?id='+id)
        .map((res:Response) => res.json())
        .subscribe(result => {
            data = result.objects;

            this.layerName = data[0].detail_url;

            this.layerName = this.layerName.replace("/layers/", "");
            this.layerName = this.layerName.replace("%3A", ":");
            console.log(this.layerName)
            //display layers
            this.wmsLayer= L.tileLayer.wms("http://192.168.0.12/geoserver/wms", {
                layers: this.layerName,
                format: 'image/png',
                transparent: true,
                version: '1.1.1',
            })
            this.map.addLayer(this.wmsLayer);

            this.getObject();
          })
     }
  }

  switchLayer(id){
      this.value = !this.value;
      console.log(this.value);
      this.addLayer(id);
    }

  getObject(){


        var owsrootUrl = 'http://192.168.0.12/geoserver/wfs';
        var defaultParameters = {
            service : 'WFS',
            version : '2.0',
            request : 'GetFeature',
            typeName : this.layerName,
            outputFormat : 'text/javascript',
            format_options : 'callback:getJson',
            SrsName : 'EPSG:4326'
        };

        var parameters = L.Util.extend(defaultParameters);
        var URL = owsrootUrl + L.Util.getParamString(parameters);
        console.log(URL)

        var select = $.getJSON(URL, function (collection) {

              var selected
              // Create new geojson layer
              new L.GeoJSON(collection, {
                // Set default style
                'style': function () {
                  return {
                    'color': 'yellow',
                  }
                }
              }).on('click', function (e) {
                // Check for selected
                if (selected) {
                  // Reset selected to default style
                  e.target.resetStyle(selected)
                }
                // Assign new selected
                selected = e.layer
                // Bring selected to front
                selected.bringToFront()
                // Style selected
                selected.setStyle({
                  'color': 'red'
                })
              }).addTo(this.map)
        })

  }

}
<div class="col-md-12">
    <div class="card">
        <div class="card-header">
            Leafmap (Leaflet) Example
        </div>
        <div id="map"></div><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    </div>
</div>

<div class="card-block">
    <table class="table">
      <thead>
          <tr>
              <th>title</th>
              <th>URL</th>
              <th>Action</th>
          </tr>
      </thead>
      <tbody>
      <tr *ngFor="let layer of vtLayer">
             
              <td>{{ layer?.title }}</td>
              <td>{{ layer?.detail_url }}</td>
              <td><ui-switch
                    [(ngModel)]="enable"
                    on-change="switchLayer(layer?.id)"
                    on-label="View"
                    off-label="Hide">
              </ui-switch>
              </td>
        </tr>
      </tbody>
    </table>
</div>
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";
import {Map} from "leaflet";
@Injectable()

export class MapService{
    public map: Map;
    public baseMaps: any;
    private vtLayer: any;

    constructor(private http: Http) {
        this.baseMaps = {
            OpenStreetMap: L.tileLayer("https://gios.jupem.gov.my/tms/gios-streets/{z}/{x}/{y}@2x.png", {
                attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
            })
        };
    }

    toggleAirPortLayer() {
      if (this.vtLayer) {
          this.map.removeLayer(this.vtLayer);
          delete this.vtLayer;
      } else {
          this.http.get("https://rawgit.com/haoliangyu/angular2-leaflet-starter/master/public/data/airports.geojson")
              .map(res => res.json())
              .subscribe(result => {
                  this.vtLayer = L.vectorGrid.slicer(result);
                  this.vtLayer.addTo(this.map);
              });
              console.log(this.vtLayer);
      }
    }
}
import {Http, Headers, Response} from "@angular/http";
import {Location} from "./core/location.class";
import {Injectable} from "@angular/core";

import "rxjs/add/operator/map";
import "rxjs/add/operator/mergeMap";

@Injectable()
export class GeocodingService {
    http: Http;

    constructor(http: Http) {
        this.http = http;
    }

    geocode(address: string) {
        return this.http
            .get("http://maps.googleapis.com/maps/api/geocode/json?address=" + encodeURIComponent(address))
            .map(res => res.json())
            .map(result => {
                if (result.status !== "OK") { throw new Error("unable to geocode address"); }

                let location = new Location();
                location.address = result.results[0].formatted_address;
                location.latitude = result.results[0].geometry.location.lat;
                location.longitude = result.results[0].geometry.location.lng;

                let viewPort = result.results[0].geometry.viewport;
                location.viewBounds = L.latLngBounds(
                  {
                    lat: viewPort.southwest.lat,
                    lng: viewPort.southwest.lng},
                  {
                    lat: viewPort.northeast.lat,
                    lng: viewPort.northeast.lng
                  });

                return location;
            });
    }

    getCurrentLocation() {
        return this.http
            .get("http://ipv4.myexternalip.com/json")
            .map(res => res.json().ip)
            .flatMap(ip => this.http.get("http://freegeoip.net/json/" + ip))
            .map((res: Response) => res.json())
            .map(result => {
                let location = new Location();

                location.address = result.city + ", " + result.region_code + " " + result.zip_code + ", " + result.country_code;
                location.latitude = result.latitude;
                location.longitude = result.longitude;

                return location;
            });
    }
}
import {ILatLng} from "./latLng.interface";
import {LatLngBounds} from "leaflet";

export class Location implements ILatLng {
    latitude: number;
    longitude: number;
    address: string;
    viewBounds: LatLngBounds;
}
export interface ILatLng {
    latitude: number;
    longitude: number;
}