phpIPAM 使用leaflet.js切换百度瓦片地图

phpIPAM使用leaflet.js加载并渲染地图,默认使用openstreetmap瓦片地图,由于众所周知的原因在国内无法加载openstreetmap底图。
经度娘了解尝试将openstreetmap地图切换为百度瓦片地图,过程如下:

一、准备

下载leaflet.ChineseTmsProviders.js到目录phpipam/js

cd /opt/phpiamp/js
wget https://jsdelivr.b-cdn.net/gh/htoooth/Leaflet.ChineseTmsProviders@master/src/leaflet.ChineseTmsProviders.js

二、使用百度API获取坐标

第一步

修改nominatim表的url字段,将openstreetmap API更换为百度地图API

http://api.map.baidu.com/geocoding/v3/?output=json&ak='Your baidu api key!'&address=
image.png

第二步

修改 phpipam/functions/classes/class.OpenStreetMap.php -> get_latlng_from_address()函数

    /**
     * Perform Geocoding lookup
     *
     * @param   string  $address
     * @return  array
     */
    public function get_latlng_from_address($address) {
        $results = ['lat' => null, 'lng' => null, 'error' => null];
        if (!is_string($address) || is_blank($address)) {
            $results['error'] = _('invalid address');
            return $results;
        }
        if (Config::ValueOf('offline_mode')) {
            $result['error'] = _('Internet access disabled in config.php');
            return $result;
        }
        try {
            // Obtain exclusive MySQL row lock
            $Lock = new LockForUpdate($this->Database, 'nominatim', 1);
            $elapsed = -microtime(true);
            // Check cached results from the last 24h
            $cached_result = $this->search_geo_cache($address, true);
            if ($cached_result) {
                $json = pf_json_decode($cached_result->lat_lng, true);
                if (is_array($json)) {
                    return $json;
                }
            }
            $url = $Lock->locked_row->url;
            //$url = $url . "?format=json&q=" . rawurlencode($address);
            //直接读取nominatim.url
            $url = $url . rawurlencode($address);

            $headers = [
                'User-Agent: phpIPAM/' . VERSION_VISIBLE . ' (Open source IP address management)',
                'Referer: ' . $this->createURL() . create_link()
            ];
            // fetch geocoding data with proxy settings from config.php
            $lookup = $this->curl_fetch_url($url, $headers);
            if ($lookup['result_code'] != 200) {
                // Lookup failed - Check cache again with no time limit.
                $cached_result = $this->search_geo_cache($address, false);
                if ($cached_result) {
                    $json = pf_json_decode($cached_result->lat_lng, true);
                    if (is_array($json)) {
                        return $json;
                    }
                }
                throw new \Exception($lookup['error_msg']);
            }
            $geo = pf_json_decode($lookup['result'], true);
            if (!is_array($geo)) {
                throw new \Exception(_('Invalid json response from nominatim'));
            }
//            if (isset($geo['0']['lat']) && isset($geo['0']['lon'])) {
//                $results['lat'] = $geo['0']['lat'];
//                $results['lng'] = $geo['0']['lon'];
//            }
//百度地图API格式数据
            if (isset($geo['result']['location']['lat']) && isset($geo['result']['location']['lng'])) {
                $results['lat'] = $geo['result']['location']['lat'];
                $results['lng'] = $geo['result']['location']['lng'];
            }

            $this->update_geo_cache($address, json_encode($results));
        } catch (\Exception $e) {
            $results = ['lat' => null, 'lng' => null, 'error' => $e->getMessage()];
        }
        // Ensure we hold the exclusive database lock for a minimum of 1 second
        // (< 1 requests/s across all load-balanced instances of this app)
        $elapsed += microtime(true);
        if ($elapsed < 0) {
            time_nanosleep(0, 1000000000);
        } elseif ($elapsed < 1) {
            time_nanosleep(0, 1000000000 * (1 - $elapsed));
        }
        return $results;
    }

三、调用百度瓦片地图

第一步

修改phpipam/index.php,找到<script src="js/leaflet.fullscreen.min.js"></script>,在下面插入

                <!--引入proj4,百度地图用--> 
                <script src="https://cdn.bootcss.com/proj4js/2.4.3/proj4.js"></script>
                <script src="https://cdn.bootcss.com/proj4leaflet/1.0.1/proj4leaflet.min.js"></script>

                <!-- 引入互联网地图插件 -->
                <script src="js/leaflet.ChineseTmsProviders.js"></script>

第二步

修改 phpipam/functions/classes/class.OpenStreetMap.php -> map()函数

    /**
     * Output OpenStreetMap HTML/JS
     *
     * @param   null|int  $height
     * @return  void
     */
    public function map($height = null)
    {
        if (sizeof($this->geodata) == 0) {
            $this->Result->show("info", _("No Locations with coordinates configured"), false);
            return;
        }

?>
        <div style="width:100%; height:<?php print isset($height) ? $height : "600px" ?>;" id="map_overlay">
            <!--百度地图 div-->
            <div id="map" style="width:100%; height:100%;"></div>
        </div>
        <script>
            function osm_style(feature) {
                return feature.properties && feature.properties.style;
            }

            function osm_onEachFeature(feature, layer) {
                if (feature.properties && feature.properties.popupContent) {
                    layer.bindPopup(feature.properties.popupContent);
                }
            }

            function osm_point_to_circle(feature, latlng) {
                return L.circleMarker(latlng, {
                    radius: 8,
                    fillColor: "#ff7800",
                    color: "#000",
                    weight: 1,
                    opacity: 1,
                    fillOpacity: 0.8
                });
            }

            var geodata = <?php print json_encode($this->geodata); ?>;
            var polydata = <?php print json_encode($this->polydata); ?>;

//            var mapOptions = {
//                preferCanvas: true,
//                attributionControl: true,
//                zoom: -1,
//                fullscreenControl: true,
//            }
            var mapOptions = { 
                crs: L.CRS.Baidu, 
                fullscreenControl: true,
                zoom: 17,
                layers:[]
            }
            var geoJSONOptions = { 
                  style: osm_style, 
                  onEachFeature: osm_onEachFeature, 
                  pointToLayer: osm_point_to_circle,
            }

//            var layerOptions = {
//                attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
//            }

            // Creating a map object
//            var map = new L.map('osmap', mapOptions);
             var map = L.map('map',mapOptions);
           // Add circuit lines
            for (var key in polydata) {
                var fmt = key.split('::::');
                if (fmt[1] == "Solid") {
                    L.polyline(polydata[key], {
                        'color': fmt[0]
                    }).addTo(map);
                } else {
                    L.polyline(polydata[key], {
                        'color': fmt[0],
                        dashArray: '20, 10'
                    }).addTo(map);
                }
            };
            // Add location markers
            geoJSON = L.geoJSON(geodata, geoJSONOptions).addTo(map);
            map.fitBounds(geoJSON.getBounds());

            // Add Tile layer
//            var layer = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', layerOptions);
            var layer = L.tileLayer.chinaProvider('Baidu.Normal.Map').addTo(map);
            map.addLayer(layer);
        </script>
<?php
    }

参考:
gisarmory/Leaflet.InternetMapCorrection: 互联网地图纠偏 (github.com)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354