python快递分拣小程序_为了监视快递小哥,我做了一个小程序!

本文介绍如何利用Python和高德地图API创建一个实时快递跟踪小程序,展示如何在地图上标注配送站,并通过监听事件来显示快递员的当前位置,帮助用户监控快递状态。
摘要由CSDN通过智能技术生成

我感觉我可以在电脑上查看快递小哥离我有多远了!

1460000006839324

6e3814e461ae865fb5e6da5c07285e47.png

我们来看一下代码。

从地图展现的程度来说,这个地图布局基本没有难度。如果你对我这么说感到疑惑那么我建议你可以看看这个: 高德地图示例中心。你应该很快可以构建出想wildGeo这样的界面。如果你对此表示有难度的话,请拷贝下面的代码到一个空白的HTML文件中:

基本地图展示

var map = new AMap.Map('container', {

resizeEnable: true,

zoom:11,

center: [116.397428, 39.90923]

});

这样你就可以在浏览器中打开一张地图了。

下面我们该干什么了? Coding!

我们需要在地图上标注配送站的信息,高德地图上叫做 自定义标记覆盖物,野狗的wildGeo工程师是这样写的:

//自定义点标记内容

var stationMarkerContent = document.createElement("div");

stationMarkerContent.className = "markerContentStyle";

//点标记中的图标

var stationMarkerImg = document.createElement("img");

stationMarkerImg.className = "markerlnglat";

stationMarkerImg.src ="http://webapi.amap.com/images/marker_sprite.png";

stationMarkerContent.appendChild(stationMarkerImg);

//点标记中的文本

var stationMarkerSpan = document.createElement("span");

stationMarkerSpan.innerHTML = '配送站';

stationMarkerSpan.setAttribute("class", "span1")

stationMarkerContent.appendChild(stationMarkerSpan);

var stationMarker = new AMap.Marker({ //AMap.Marker是非常重要的点,关于样式如果不是很符合你的要求,你可以手动去改!

map:map,

position:new AMap.LngLat(116.408032,39.897614),//基点位置

autoRotation:false,

content: stationMarkerContent //自定义点标记覆盖物内容,这个地方可以直接写HTML文件

});

野狗工程师在做wildGeo用的是JavaScript来做的,他定义了一个 stationMarkerContent 来盛放自定义标记覆盖物的内容。之后把标价覆盖物的HTML代码构造好了放到了 AMap.Marker 对象的content中。你当然可以直接在content中写好你构造好的HTML代码字符串。

完成以上的步骤,客户实现的效果是,一张地图,之后会有一个配送站地理位置图标,和配送站三个文字。

因为我们需要确定是地图上任意一个点上某个范围内的送餐员电话,所以我们需要一某个点为中心画圆,当然,高德地图给我们提供了这样的一个接口。

var circle = new AMap.Circle({

map:map,//map指的是你创建的地图对象,就是这篇文章第五个代码块中的那个map对象

center:loc,// 圆心位置

radius:(1500), //半径

strokeColor: "#6D3099", //线颜色

strokeOpacity: 1, //线透明度

strokeWeight: 3, //线粗细度

fillColor: "#B650FF", //填充颜色

fillOpacity: 0.35//填充透明度

});

之后地图上会有一个出现一个表示范围的圆环。下面就是野狗实施后端云大显身手的时间了! 别忘记注册 野狗 账号

首先,如果你要通过 ctrl+c 和 ctrl+p 之后代码就可以使用的话,你一定要了解后台的数据结构。wildGeo数据结构如下:

{

"_geofire": {

"beijing:0000": {

"g": "wx4dwxwtp8",

"l": [

39.856513,

116.310528

]

},

"beijing:0001": {

"g": "wx4en9qsrw",

"l": [

39.909971999999996,

116.310528

]

},

"beijing:0100": {

"g": "wx4f8rstp8",

"l": [

39.856513,

116.3846855

]

},

"beijing:0101": {

"g": "wx4g03ksrw",

"l": [

39.909971999999996,

116.3846855

]

}

},

"beijing": {

"delivery": {

"0000": {

"id": "0000",

"lat": 39.856513,

"lng": 116.310528

},

"0001": {

"id": "0001",

"lat": 39.909971999999996,

"lng": 116.310528

},

"0100": {

"id": "0100",

"lat": 39.856513,

"lng": 116.3846855

},

"0101": {

"id": "0101",

"lat": 39.909971999999996,

"lng": 116.3846855

}

}

}

}

你们一定要明白数据结构和数据的区别!你可以把上面的数据复制到本地的一个json文件中,之后导入到你的野狗app里面去。

之后建立也野狗对象

//map variable

var map;

// Set the center as Wilddog HQ

var locations = {

"WilddogHQ": [39.897614,116.408032]

};

var center = locations["WilddogHQ"];

// Get a reference to the Wilddog public transit open data set

var transitWilddogRef = new Wilddog("https://.wilddogio.com/")

野狗为了更好的和地图是进行适配,开发了wildGeo对象,他是一个单独的js,有兴趣的开发者可以 下载 或 阅读文档

我们在建立了transitwilddogRef对象的基础上,需要尽力wildGeo对象。

// Create a new WildGeo instance, pulling data from the public transit data

var wildGeo = new WildGeo(transitWilddogRef.child("_geofire"));

上面的代码说明了,创建wildGeo对象来操作地理坐标数据,数据来源于transitWilddogRef下面的_geofire节点。

之后,我们来看一下怎样数据初始化。

/*************/

/* GEOQUERY */

/*************/

// Keep track of all of the deliverys currently within the query

var deliverysInQuery = {};

// Create a new GeoQuery instance

var geoQuery = wildGeo.query({

center: center, //center指的是 var center = locations["WilddogHQ"];

radius: 1500

});

/* Adds new delivery markers to the map when they enter the query */

geoQuery.on("key_entered", function(deliveryId, deliveryLocation) {

// Specify that the delivery has entered this query

deliveryId = deliveryId.split(":")[1];

deliverysInQuery[deliveryId] = true;

// Look up the delivery's data in the Transit Open Data Set

transitWilddogRef.child("beijing/delivery").child(deliveryId).once("value", function(dataSnapshot) {

// Get the delivery data from the Open Data Set

delivery = dataSnapshot.val();

// If the delivery has not already exited this query in the time it took to look up its data in the Open Data

// Set, add it to the map

if (delivery !== null && deliverysInQuery[deliveryId] === true) {

// Add the delivery to the list of deliverys in the query

deliverysInQuery[deliveryId] = delivery;

// Create a new marker for the delivery

delivery.marker = createdeliveryMarker(delivery);

}

});

});

我们需要观察几个点:

第一个点是wildGeo.query() 之后会产生一个新的对象叫做:geoQuery。

geoQuery.on(eventType,callback) eventType是事件类型:这里用的是key_entered,表示监听的点是否进入范围之内。如果进入则存到deliverysInQuery对象中去,通过createdeliveryMarker方法,在地图上创建一个个的快递员图标。

那么如果快递离开了我们的那个范围呢?

geoQuery.on("key_exited", function(deliveryId, deliveryLocation) {

// Get the delivery from the list of deliverys in the query

deliveryId = deliveryId.split(":")[1];

var delivery = deliverysInQuery[deliveryId];

// If the delivery's data has already been loaded from the Open Data Set, remove its marker from the map

if (delivery !== true && typeof delivery.marker !== "undefined") {

delivery.marker.stopMove();

delivery.marker.setMap(null);

}

// Remove the delivery from the list of deliverys in the query

delete deliverysInQuery[deliveryId];

});

我们可以使用key_exited这个方法,来监听离开我们的快递员。

最后附上createdeliveryMarker方法。

/**********************/

/* HELPER FUNCTIONS */

/**********************/

/* Adds a marker for the inputted delivery to the map */

function createdeliveryMarker(delivery) {

//自定义点标记内容

var markerContent = document.createElement("div");

markerContent.className = "markerContentStyle";

//点标记中的图标

var markerImg = document.createElement("img");

markerImg.className = "markerlnglat";

markerImg.src = "images/man.png";

markerImg.height = "35";

markerImg.width = "27";

markerContent.appendChild(markerImg);

//点标记中的文本

var markerSpan = document.createElement("span");

markerSpan.innerHTML = delivery.id;

markerContent.appendChild(markerSpan);

var marker = new AMap.Marker({

map:map,

position:new AMap.LngLat(delivery.lng, delivery.lat),//基点位置

autoRotation:false,

content: markerContent //自定义点标记覆盖物内容

});

return marker;

}

和地图初始化代码片段

function initializeMap() {

var loc = new AMap.LngLat(center[1], center[0]);

//初始化地图对象,加载地图

var UA = navigator.userAgent;

if (UA.indexOf("Mobile") == -1 || UA.indexOf("Mobile") == -1) {

defineMap(loc, 15);

} else {

defineMap(loc , 13);

};

//加载工具条

// map.plugin(["AMap.ToolBar"],function(){

// var tool = new AMap.ToolBar();

// map.addControl(tool);

// });

//

// //加载比例尺

// map.plugin(["AMap.Scale"],function(){

// var scale = new AMap.Scale();

// map.addControl(scale);

// });

var circle = new AMap.Circle({

map:map,

center:loc,// 圆心位置

radius:((radiusInKm) * 1000), //半径

strokeColor: "#6D3099", //线颜色

strokeOpacity: 1, //线透明度

strokeWeight: 3, //线粗细度

fillColor: "#B650FF", //填充颜色

fillOpacity: 0.35//填充透明度

});

//自定义点标记内容

var stationMarkerContent = document.createElement("div");

stationMarkerContent.className = "markerContentStyle";

//点标记中的图标

var stationMarkerImg = document.createElement("img");

stationMarkerImg.className = "markerlnglat";

stationMarkerImg.src ="http://webapi.amap.com/images/marker_sprite.png";

stationMarkerContent.appendChild(stationMarkerImg);

//点标记中的文本

var stationMarkerSpan = document.createElement("span");

stationMarkerSpan.innerHTML = '配送站';

stationMarkerSpan.setAttribute("class", "span1")

stationMarkerContent.appendChild(stationMarkerSpan);

var stationMarker = new AMap.Marker({

map:map,

position:new AMap.LngLat(116.408032,39.897614),//基点位置

autoRotation:false,

content: stationMarkerContent //自定义点标记覆盖物内容

});

var lnglat;

var clickEventListener = AMap.event.addListener(map,'click',function(e){

lnglat=e.lnglat;

circle.setCenter(lnglat);

updateCriteria();

});

var updateCriteria = _.debounce(function() {

lnglat = circle.getCenter();

geoQuery.updateCriteria({

center: [lnglat.getLat(), lnglat.getLng()],

radius: radiusInKm

});

}, 10);

}

累死妹子了!

作为一个博爱的程序媛,我还要一定要做这个事情(为什么我写了这句话感觉到好邪恶!):

鉴于本人是一个前端攻城狮,所以这两个版本的东西我也就只能给你们一个链接吧,各位IOS攻城狮和Android攻城狮,来玩玩么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值