zl程序教程

您现在的位置是:首页 >  其他

当前栏目

高质量编码--Excel POI点高德地图展示

2023-02-25 18:21:45 时间

Excel文件里记录着POI点信息(包含经纬度),这些记录也可以分类别保存在不同的sheet里。下面介绍如何根据sheet名称,自动把Excel里的点位信息在地图上分组点标记展示,地图展示选用高德地图API。

后台开发使用Python Web框架 Tornado,代码如下:

import pandas as pd
from tornado.options import define,options
import tornado.ioloop
import tornado.web
import os

define('port',default=8000,help='run on the given port',type=int)

class cross_originAllowed_Handler(tornado.web.RequestHandler):
    def initialize(self):
        self.set_header('Access-Control-Allow-Origin','*')
        self.set_header('Access-Control-Allow-Methods','POST,GET')
        self.set_header('Access-Control-Max-Age',1000)
        self.set_header('Access-Control-Allow-Headers','*')
class ApiHandler(cross_originAllowed_Handler):
    def get(self):
        excel=pd.ExcelFile('db.xlsx')
        result={}
        for sheet_name in excel.sheet_names:
            df=pd.read_excel(excel,sheet_name)
            result[sheet_name]=json.loads(df.to_json(orient='records'))    
        self.write(result)
        return 

class mapHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html') 

def make_app():
    return tornado.web.Application(
        [
        (r"/api.json", ApiHandler),
         (r"/", mapHandler),
    ],
        static_path=os.path.join(os.path.curdir,'static'),
        template_path=os.path.join(os.path.curdir,'template'),
        debug=True)

if __name__ == "__main__":
    app = make_app()
    options.parse_command_line()
    app.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

地图展示页面使用高德地图JavaScript API,代码如下:

<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"> 
 <script type="text/javascript" src="https://underscorejs.net/js/jquery-1.11.0.min.js"></script>  
 <script type="text/javascript" src="https://underscorejs.net/js/underscore.js"></script>  

 <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=yourkey"></script> 
 <script type="text/template" id="toggleTemplate">
 <% _.each(layers,(points,name)=> { %>
 <div class="radio-group"><a class="radio-button radio-button-checked" data-layer="<%=name%>" onclick="javascript:void(0);"><span class="radio-button-inner"><%=name%></span></a> </div>
 
 <% }) %>
        <div class="radio-group"><a title="点击切换名称显示" id="toggleLabel" data-label="name" class="radio-button" onclick="javascript:void(0);"><span class="radio-button-inner" >名称</span> </a><a title="点击切换地图风格" id="toggleStyle" class="radio-button" onclick="javascript:void(0);" data-style='normal'><span class="radio-button-inner">标准</span> </a> </div>

 </script>
 
 <script type="text/template" id="infoTemplate">
 <% _.each(row,(value,col)=> { %>
  <%=col %>:<%=value %><br>
 <% }) %>
 </script>
<style>
body.darkblue .amap-marker-label{
background:#000001;
color:white;
border:1px solid white;
}
body.normal .amap-marker-label{
background:white;
color:black;
border: 1px solid  black;
}
#container {width:100%; height: 100%; }  
   #mapgroup .radio-button-wrapper {
            width: 80px;
            padding: 0 !important;
            text-align: center;
            border: 0 !important;
            background: rgba(0, 0, 0, .6) !important;
            color: #fff !important;
            border-radius: 0 !important;
        }

        .mapgroup {
            position: fixed;
            right: 0;
            top: 23%;
            z-index: 999;
            width: 80px;
        }
		
		 .radio-group {
            width: 80px;
            display: grid;
            cursor: pointer;
        }

        .white .radio-button,
        .radio-button {
            background-color: white;
            color: #000;
			user-select: none;
            line-height: 40px;
            text-align: center;

            text-decoration: none;
            border: 1px solid black;
            border-radius: 10px;
            caret-color: transparent;
        }

        .dark .radio-button {
            background-color: black;
            color: #fff;

            line-height: 40px;
            text-align: center;

            text-decoration: none;
            border: 1px solid white;
            border-radius: 10px;
            caret-color: transparent;
        }

        .radio-button-checked,
        .white .radio-button-checked,
        .dark .radio-button-checked {
            background-color: #337ab7;
            color: #fff;
            caret-color: transparent;
        }

</style>
</head>

<body>
<div id="container"></div> 
      <div id="mapgroup" class="mapgroup" contenteditable="false">
        
    </div>

</body>
 
<script type="text/javascript" >
   var map = new AMap.Map('container',{
       zoom: 12,
       center: [113.667116,34.776845]
   });
 
 
 
var infoTemplate=_.template($('#infoTemplate').html());
   var infoWindow = new AMap.InfoWindow({
   });
 var toggleTemplate=_.template($('#toggleTemplate').html());
  $.get('../api.json',function(data){
   

 
 layers=	_.mapObject(data,(table,name)=>{
  var markers=_.map(table,row=>{
  console.log(row);
  var lng=row["经度"];
  var lat=row["纬度"];
  
  console.log(lng,lat);
  var marker = new AMap.Marker({
    position: new AMap.LngLat(parseFloat(lng), parseFloat(lat)),   
    title: row['名称'],
	icon: `../static/imgs/${name}.png`,
});
var row0=_.omit(row,['经度','纬度','名称']);
marker.content = infoTemplate({row:row0});
        marker.on('click', markerClick);
    
    
return marker;

})
 map.add(markers);
   return markers;
})
function markerClick(e) {
        infoWindow.setContent(e.target.content);
        infoWindow.open(map, e.target.getPosition());
    }
  $('#mapgroup').html(toggleTemplate({layers:data}));
  map.setFitView();
  
    })
  
 $('#mapgroup').delegate('#toggleStyle','click',function () {
         var labelType= $(this).data('style');
		 if (labelType == 'normal') {
       var styleName = "amap://styles/darkblue" ;
     $(this).data('style','darkblue').addClass('radio-button-checked').find('span').text('暗夜');
	  $('body').removeClass('normal').addClass('darkblue');
	  }
	  else {
	   var styleName = "amap://styles/normal" ;
	 $(this).data('style','normal').removeClass('radio-button-checked').find('span').text('标准');
	 $('body').removeClass('darkblue').addClass('normal');
	  }
	   map.setMapStyle(styleName);
    })

    $('#mapgroup').delegate('#toggleLabel','click',function () {
        var labelType = $(this).data('label');
         
        if (labelType == 'none') {
            $(this).data('label', 'name');
            $(this).removeClass('radio-button-checked');
			_.each(layers,(markers,name)=>{
			_.each(markers,marker=>{
			marker.setLabel({
        offset: new AMap.Pixel(0, 0), 
        content:'',  
        direction: 'top'  
    });
			})
        })
		}
        else if(labelType == 'name') {
            $(this).data('label', 'none');
            $(this).addClass('radio-button-checked');
		_.each(layers,(markers,name)=>{
		_.each(markers,marker=>{
			marker.setLabel({
        offset: new AMap.Pixel(0, 0), 
        content: marker.getTitle(),  
        direction: 'top'  
    });
			})
			})
        }

    });
	$('#mapgroup').delegate('.radio-group [data-layer]','click',function () {
	var name=$(this).data('layer');
	if($(this).hasClass('radio-button-checked')){
	$(this).removeClass('radio-button-checked');
	_.each(layers[name],marker=>{
			marker.hide();
	})
	}
else{
$(this).addClass('radio-button-checked');
_.each(layers[name],marker=>{
			marker.show();
	})
}

 
})
  
</script>
</html>