Leaflet(1) ----- leaflet + Ge

作者: woow_wu7 | 来源:发表于2018-06-10 23:32 被阅读147次

    (一) 安装

    yarn add leaflet
    

    (二) 使用

    (1) 在index.html中添加地图显示的容器

    index.html
    
    <div id="map" style="width:1000px; height:700px; display:block; margin: 10px"></div>
    
    
    
    
    也可以把leaflet的css文件引入index.html ----- 则在js页面不引入
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.1.0/dist/leaflet.css" integrity="sha512-wcw6ts8Anuw10Mzh9Ytw4pylW8+NAD4ch3lqm9lzAsTxg0GFeJgoAtxuCLREZSC5lUXdVyo/7yfsqFjQ4S+aKw==" crossorigin="" />
    
    
    

    (2) 引入并使用

    import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
    import L from 'leaflet';                     // 引入leaflet js
    import 'leaflet/dist/leaflet.css';           // 引入leaflet css
    
    class App extends Component {
      constructor(props) {
        super(props)
        this.map = null                          // 初始化map属性
      }
      componentDidMount() {
        const MAP = this.map = L.map('map', {    // 加载leaflet中心类   --- map类
          center: [39.9788, 116.30226],          // L.map(容器id, 配置项 )
          zoom: 18
        })
    
        L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
          subdomains: "1234",
          attribution: '高德地图'
        }).addTo(this.map);                 // 把瓦片图层添加到map上,map需要加载地图图层,即显示的内容
    
      }
      render() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <h1 className="App-title">Welcome to React</h1>
            </header>
          </div>
        );
      }
    }
    
    export default App;
    
    



    22222.jpg

    map 常用配置项

        const MAP = this.map = L.map('map', {   // L.map(DOM, options)
          center: [39.9788, 116.30226],    // 初始化地图的地理中心
          zoom: 18,                        // 缩放
          zoomControl: true,               // 缩放控制开启和关闭
          attributionControl: true,        // 属性控制,可以通过 L.tileLayer().getAttribution()得到
          dragging: true,                  // 拖动控制
          layers: [tileX],                 // 初始化加载的图层     ---- 重要重要重要
          maxZoom: 18,                     // 最大缩放
          minZoom: 1,                      // 最小缩放
          crs: L.CRS.EPSG3857,      //要使用的坐标参考系统,默认的坐标参考系,互联网地图主流坐标系
         // crs: L.CRS.EPSG4326,    //WGS 84坐标系,GPS默认坐标系
        })
    
    
         crs 是 Coordinate Reference System 的缩写   -------  坐标参考系统
    

    TileLayer常用配置项

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}{r}.png?{foo}', {foo: 'bar'}).addTo(..)
    
    {s}:       subdomains 表示可用的子域
    {z}:       zoom 表示缩放
    {x}, {y}:  tile coordinates 表示坐标
    {r} :      can be used to add "@2x" to the URL to load retina tiles
    
    L.tileLayer(url, options)
    
    const tileX = L.tileLayer(url, {
       subdomains: "1234",
       attribution: '高德地图'
     });
    

    marker,popup,tooltip

    
        const marker = L.marker([39.9788, 116.30226]).addTo(this.map);  // 添加marker到地图
    
        marker.bindPopup('点击marker,显示popup')   // 给marker绑定Popup,点击marker时显示
    
        marker.bindTooltip("my tooltip text")    // 给marker绑定tooltip,hover时显示
    
        const marker2 = L.marker([39.9790, 116.30248], {    // marker的属性配置
          title: '这是marker2的title',
          icon:L.icon({                         // 更换maker的图标
            iconUrl: 'my-icon.png',
            iconSize: [38, 95],
            iconAnchor: [22, 94],
            popupAnchor: [-3, -76],
            shadowUrl: 'my-icon-shadow.png',
            shadowSize: [68, 95],
            shadowAnchor: [22, 94]
          })
        }).addTo(this.map)
    

    circle,polyline,polygon多边形,rectangle矩形

       L.circle([39.9788, 116.30226], {radius: 50}).addTo(this.map);        // 圆
    
        var latlngs = [
          [39.9790, 116.30248],
          [39.9790, 116.30270],
          [39.9793, 116.30270],
          [39.9790, 116.30290],
        ];
        var latlngs2 = [
          [39.9790, 116.30208],
          [39.9790, 116.30250],
          [39.9793, 116.30250],
          [39.9790, 116.30208],
        ];
        var latlngs3 = [
          [45.51, -122.68],
          [37.77, -122.43],
          [34.04, -118.2]
      ];
      var polyline = L.polyline(latlngs, {color: 'red'}).addTo(this.map);      // 线条
      this.map.fitBounds(polyline.getBounds());               //填充边界,定位地图
     
      var latlngs = [latlngs];
      var polygon = L.polygon(latlngs2, {color: 'green'}).addTo(this.map);   // 多边形
      this.map.fitBounds(polygon.getBounds());
    
      var polyline = L.polyline(latlngs3, {color: 'red'}).addTo(this.map);
    
    
    
     // define rectangle geographical bounds     
     // geographical 地里的
     var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
     // create an orange rectangle
     L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);
     // zoom the map to the rectangle bounds
     map.fitBounds(bounds);
    
    

    添加图片做为地图

    let imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
    let imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];  
    // 注意: bounds是边界,是 ( southWest ) 和 ( northEast ) 的值
    
    L.imageOverlay(imageUrl, imageBounds).addTo(map);
    

    获取用户当前的位置信息

    地理位置 API 通过 navigator.geolocation 提供

    • navigator.geolocation 获取地理位置
    • getCurrentPosition 函数获取用户当前定位位置。
     const xyz = navigator.geolocation.getCurrentPosition((x) => {
        const xi = x.coords.latitude;
        const yi = x.coords.longitude;
        L.marker([xi, yi]).addTo(MAP);   // 用marker显示在地图上
     });
    

    切换不同图层

    class App extends Component {
      constructor(props) {
        super(props);
        this.map = null
      }
      componentDidMount() {
    
        const gaode = L.tileLayer('...', {
          subdomains: "1234",
          attribution: '高德地图'
        })
    
        const mapbox = L.tileLayer( '...', {
          attribution: '谷歌地图',
          subdomains: "1234",
        })
    
        var mymap = this.map = L.map('map', {
          center: [39.9788, 116.30226],
          zoom: 18,
          layers: [mapbox],
          drawControl: true
        })
    
        L.control.layers({            // L.control.layers
          '高德地图': gaode,
          '谷歌地图': mapbox,
        }).addTo(this.map)
    }
    
    

    把GeoJSON中的 coordinates 转换成 LatLng

    
        const aaa = [39.9788, 116.30226];
        const bbb = L.GeoJSON.coordsToLatLng(aaa);
        console.log(bbb)     
        // LatLng {lat: 116.30226, lng: 39.9788}
    
    
        const ccc = L.GeoJSON.latLngToCoords(bbb);
        console.log(ccc)
        // [39.9788, 116.30226]
      
    





    GeoJSON对象

    GeoJSON是一种对各种地理数据结构进行编码的格式。
    GeoJSON对象可以表示几何、特征或者特征集合。(geometry, feature, featureCollection
    GeoJSON支持这几种 几何类型:点、线、面、多点、多线、多面和几何集合。
    GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。

    • GeoJSON对象必须由一个名字为"type"的成员。这个成员的值是由GeoJSON对象的类型所确定的字符串。
      type成员的值必须是下面之一:"Point"点, "MultiPoint"多点, "LineString", "MultiLineString", "Polygon", "MultiPolygon", "GeometryCollection"几何集合, "Feature", 或者 "FeatureCollection"特征集合
    • GeoJSON对象可能有一个可选的"crs"成员,它的值必须是一个坐标参考系统的对象
      crs 是 Coordinate Reference System 的缩写 ------- 坐标参考系统
    • GeoJSON对象可能有一个"bbox"成员,它的值必须是边界框数组
      boundary边界

    (1) 几何对象 geometry

    geometry对象包含 ( type属性 ) 和 ( coordinates属性 - 总是数组 )

    • 几何是一种GeoJSON对象,这时type成员的值是下面字符串之一:"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", 或者"GeometryCollection"。

    • 除了“GeometryCollection”外的其他任何类型的GeoJSON几何对象必须由一个名字为"coordinates"的成员。coordinates成员的值总是数组。这个数组里的元素的结构由几何类型来确定。

    (2) 位置 coordinates

    coordinates 总是数组 (数组或者嵌套数组)

    • 位置是基本的几何结构。几何对象的"coordinates"成员由一个位置(这儿是几何点)、位置数组(线或者几何多点),位置数组的数组(面、多线)或者位置的多维数组(多面)组成。

    • 位置由数字数组表示。必须至少两个元素,可以有更多元素。元素的顺序必须遵从x,y,z顺序(投影坐标参考系统中坐标的东向、北向、高度或者地理坐标参考系统中的坐标长度、纬度、高度

    (3) 特征对象 Feature

    Feature对象必须包含 ( geometry属性 ) 和 ( properties属性 )

    类型为"Feature"的GeoJSON对象是特征对象。

    • 特征对象必须由一个名字为"geometry"的成员,这个几何成员的值是上面定义的几何对象或者JSON的null值。
    • 特征对戏那个必须有一个名字为“properties"的成员,这个属性成员的值是一个对象(任何JSON对象或者JSON的null值)。
    • 如果特征是常用的标识符,那么这个标识符应当包含名字为“id”的特征对象成员。

    (4) 特征集合对象 FeatureCollection

    FeatureCollection对象必须包含 ( features属性 ),是一个数组

    类型为"FeatureCollection"的GeoJSON对象是特征集合对象。

    • 类型为"FeatureCollection"的对象必须由一个名字为"features"的成员。与“features"相对应的值是一个数组。这个数组中的每个元素都是上面定义的特征对象
    { "type": "FeatureCollection",   // GeoJSON对象必须有个type属性,这里值是 特征集合
      "features": [
        { "type": "Feature",      // Feature<Point>
          "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},  // Geometry<Point>
          "properties": {"prop0": "value0"}
          },
        { "type": "Feature",    // 线数据
          "geometry": {
            "type": "LineString",
            "coordinates": [
              [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
              ]
            },
          "properties": {
            "prop0": "value0",
            "prop1": 0.0
            }
          },
        { "type": "Feature",
           "geometry": {
             "type": "Polygon",   // 多边形数据
             "coordinates": [
               [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
                 [100.0, 1.0], [100.0, 0.0] ]
               ]
           },
           "properties": {
             "prop0": "value0",
             "prop1": {"this": "that"}
             }
           }
         ]
       }
    





    // 2018.6.9更 -------------- // 复习面向对象

            // 构造函数
                // 1. 首字母大写
                // 2. 函数内部使用this代表将要生成的实例对象
                // 3. 使用new命令,执行构造函数,返回实例对象
            
            // 忘记写 new命令
                // 在构造函数内部使用 'use strict'严格模式,在忘记new命令时,就会报错
    
            // return 
                // 构造函数内部,如果有return语句,
                    // 1. return 后面跟一个对象,new命令就会返回该对象
                    // 2. return 后满跟的不是一个对象, new就会返回this指代的实例对象
    
            // 对普通函数使用new命令,return后面跟的不是对象,会返回一个空对象
    
            // new命令总是返回一个对象,实例对象,或者return 指定的对象, 普通函数使用new命令,返回空对象或者return 指定的对象
    
            // Object.create() 创建实例对象
                // 1.构造函数为模板,可以生成实例对象,但有时,拿不到实例对象,只能通过现有的对象为模板,生成实例对象
    
            // ------------------------------------------------
            
            // this
                // this不管用在什么场合,都是返回一个对象
    
                // this是属性和方法当前所在的对象
                    // 对象的属性可以赋值给另一个对象,所以,属性所在的当前对象是可变的,即 this的指向是可变的
                    
                // 只要函数被赋值给另一个变量,this的指向就会变
                
                // 总结
                    // this是函数运行时所在的对象 !!!!
                        // 在js中一切皆对象,运行环境也是对象,所以,函数都在某个对象中运行
                        // this就是函数运行时所在的对象
    
                // this的使用场合
                    // 1.全局环境
                        // 全局环境使用this, this指的是顶层对象,即window对象
                    // 2.构造函数
                        // 在构造函数中,this指向将要生成的实例对象
                    // 3.对象的方法
                        // 在对象的方法中,this指向方法运行时,所在的对象
                // 注意
                    // 如果this所在的方法不在对象的第一层,this只是指向当前一层的对象,而不会继承更上面的层 !!
                    
                    // 如果,将嵌套对象内部的方法赋值给一个变量,this依然会指向全局对象window 
    
                    // 嵌套的this
                        // 使用一个变量固定this的值,然后内层函数调用这个变量,是非常常见的做法
    
                // Function.prototype.call(参数1, 参数2, ....)
                    // 函数实例的call方法,可以指定函数内部this的指向,然后在所指定的作用域中,调用该函数
    
                    // call()方法的参数是一个 对象, 如果参数是空,null, undefined,则默认传入全局对象
    
                    // call()方法可以传入多个参数,第一个参数是所要绑定的对象,后面的参数是函数调用时传入的参数
    
                    // call()方法会自动调用函数 ---- bind()方法则不会自动调用
    
                // Function.prototype.apply(参数1, [参数2, 参数3 , ...])    
                    // apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。
                    // 唯一的区别就是,它接收一个数组作为函数执行时的参数
    
                // Function.prototype.bind(参数1, 参数2, ....)
                    // bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数
        
    

    算法:

    1. 找出数组中最大的元素
    var a = [1,11,111,30,40];
    const b = Math.max.apply(null, a);   // Math.max() 是一个函数
    console.log(b) // 111
    
    Function.prototype.apply(需要绑定的对象,数组参数) // 第一个参数时null和undefined时,绑定全局对象
    
    
    1. 将数组的 ( 空元素 ) 替换成 ( undefined )
    Array.apply(null, ['a', ,'b'])
    
    // [ 'a', undefined, 'b' ]
    

    prototype对象

    1. 构造函数的缺点
      同一个构造函数的多个实例,无法共享属性。(造成系统资源的浪费)
      构造函数的属性和方法都会生成在实例对象上
       const A = function() {
         this.name = function() {
            console.log('not equal')
          }
        };
        const b = new A();
        const c = new A();
        console.log(b.name === c.name)  // false
    
      // 构造函数的name方法,会定义在实例对象上,即 每个实例都会生成name方法
    
    1. 原型对象prototype
      原型对象的所有属性和方法都能被实例对象所共享

    2. js规定,每一个函数都有一个prototype属性,指向一个对象
      对于普通函数来说,该属性基本无用。但是,对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的原型。

    • 对于构造函数来说,构造函数的prototype属性,会在构造函数生成实例对象的时候,自动成为实例对象的原型对象!!!
      // 对于构造函数,prototype属性会在生成实例对象的时候,成为实例对象的原型对象
      // 原型对象的属性和方法,被实例对象所共享
    • 原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。
    • 当实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法。
      如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。

    总结: 原型对象的作用就是定义所有实例对象所共享的属性和方法,这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象。

    function Animal(name) {
      this.name = name;
    }
    Animal.prototype.color = 'white';   // 任何函数的prototype属性都指向一个对象
    
    var cat1 = new Animal('大毛');
    var cat2 = new Animal('二毛');
    
    cat1.color // 'white'
    cat2.color // 'white'
    
    // 对于构造函数,prototype属性会在生成实例对象的时候,成为实例对象的原型对象
    // 原型对象的属性和方法,被实例对象所共享
    

    原型链

    1. JavaScript 规定,所有对象都有自己的原型对象(prototype)。
      一方面,任何一个对象,都可以充当其他对象的原型;
      另一方面,由于原型对象也是对象,所以它也有自己的原型。
      因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……
    2. 如果一层层上溯,所有对象的原型最终可以上溯到Object.prototype
      ( 即Object构造函数的prototype属性 )
    • 所有对象都继承了Object.prototype属性上的 属性和方法
      这就是所有对象都有valueOf和toString方法的原因,因为这是从Object.prototype继承的。
    • Object.prototype的原型是null,由于null没有任何属性,所以原型链到此为止。

    3.读取属性时,如果本身对象没有该属性,就是上溯到该对象的原型对象上寻找,如果还没有,就一个向上到Object.prototype,如果还没有就返回 undefined

    4.自身和原型有同名属性时,优先读取自身对象上的属性 ------ 这叫做"覆盖"。

    5. constructor 属性

    prototype对象默认有一个constructor属性,指向prototype对象所在的构造函数

    function P() {}
    P.prototype.constructor === P // true
    
    • constructor属性定义在prototype对象上,因此,可以被实例对象所继承
    const A = function() {
       console.log('这是一个构造函数')
    };
    const b = new A();
    
    console.log( A.prototype.constructor === b.constructor );  //true
    console.log( A.prototype.constructor === A);  //true
    console.log( b.constructor === A);   //true
    console.log( b.hasOwnProperty('constructor'));  // false ------- 不是自身属性
    
    1. constructor属性的作用
    • 1.constructor属性的作用,可以得知,实例对象到底是由哪个构造函数产生的
      1. 有了constructor,就可以从一个实例对象新建另一个实例对象
    
         const A = function() {
             console.log('这是构造函数A');
         };
    
         const b = new A();
    
         const c = new b.constructor();    // b.constructor === A === A.prototype.constructor
    
         console.log( c instanceof A );     // c 是 A 的实例    ----- 注意 instanceof 是小写 of
    
    
    • 修改原型对象时,一般要同时修改 constructor 属性
    1. constructor.name构造函数的名称
    function Foo() {}
    var f = new Foo();
    f.constructor.name // "Foo"
    

    8. instanceof 运算符

    instanceof 返回一个boolean布尔值,表示对象是否是构造函数的实例

    var v = new Vehicle();
    
    v instanceof Vehicle // true
    
    // instanceof是 实例的意思
    

    instanceof运算符的左边是实例对象,右边是构造函数。

    1. instanceof会检查右边构建函数的原型对象(prototype),是否在左边对象的原型链上。
      因此,下面两种写法是等价的。
    var v = new Vehicle();
    
    v instanceof Vehicle
    // 等同于
    Vehicle.prototype.isPrototypeOf(v)
    
    特例:

    instanceof的原理是检查右边构造函数的prototype属性,是否在左边对象的原型链上。
    有一种特殊情况,就是左边对象的原型链上,只有null对象。这时,instanceof判断会失真。

    instanceof的用处:

    instanceof运算符的一个用处,是判断值的类型。

    • 注意,instanceof运算符只能用于对象,不适用原始类型的值。
    var x = [1, 2, 3];
    var y = {};
    x instanceof Array // true
    y instanceof Object // true
    
    console.log(typeof x)   // object  ---- 注意:数组的typeof是object
    
    
    
    -----------------------------------------------
    注意: instanceof只能用于对象,不能用于原始类型的值
    var s = 'hello';
    s instanceof String // false
    


    object对象的相关方法

    Object.getPrototypeOf()

    Object.getPrototypeOf方法返回参数对象的原型。这是获取原型对象的标准方法。

    • Object.getPrototypeOf() 返回参数对象的原型对象
    var F = function () {};
    var f = new F();
    Object.getPrototypeOf(f) === F.prototype // true
    
    
    -----------------------------------------------------------------
    
        const a = {};
        const b = {name: 'wang'};
        a.__proto__ = b;
        console.log(a.name)   // wang
    
        // a.__proto__ = b  等价于  Object.setPrototypeOf(a,b);     !!!!!!!!!
    
    • 注意:
      根据语言标准,proto属性只有浏览器才需要部署,其他环境可以没有这个属性。它前后的两根下划线,表明它本质是一个内部属性,不应该对使用者暴露。因此,应该尽量少用这个属性,而是用Object.getPrototypeof()和Object.setPrototypeOf(),进行原型对象的读写操作。


    获取实例对象的原型对象有三种方法

    1. obj.__proto__
    2. obj.constructor.prototype
    3. Object.getPrototypeOf(obj)
    
    
    
    上面三种方法之中,前两种都不是很可靠。
    
    __proto__属性只有浏览器才需要部署,其他环境可以不部署。
    
    而obj.constructor.prototype在手动改变原型对象时,可能会失效。
    


    Object.getOwnPropertyNames()

    Object.getOwnPropertyNames方法返回一个数组,成员是参数对象本身的所有属性的键名,不包含继承的属性键名。

    Object.prototype.hasOwnProperty()

    hasOwnProperty ------------- 自身属性

    对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。

    hasOwnProperty方法是 JavaScript 之中唯一一个处理对象属性时,不会遍历原型链的方法。!!!!!!!!!!

    • hasOwnProterty是唯一一个处理对象属性时,不会遍历原型链的方法 !!!

    in 运算符 ------------------- 不区分自身属性和继承属性

    in运算符返回一个布尔值,表示一个对象是否具有某个属性。它不区分该属性是对象自身的属性,还是继承的属性。

    对象的拷贝

    如果要拷贝一个对象,需要做到下面两件事情。

    1. 确保拷贝后的对象,与原对象具有同样的原型。
    2. 确保拷贝后的对象,与原对象具有同样的实例属性。
    • 拷贝对象需要做到两点,与元对象具有相同的原型和相同的实例属性

    相关文章

      网友评论

        本文标题:Leaflet(1) ----- leaflet + Ge

        本文链接:https://www.haomeiwen.com/subject/nifrsftx.html