nodejs-初探-简单的判定位置是否在市区API

看来nodejs还是越来越火了,WordPress也用上了nodejs抛弃了php,虽然php7比php5的效率高了一倍,然而在node,java等静态语言面前,还是不值一提.当然php还是有他的好处,开发迅速,修改便捷,适宜于调用api做应用层.另外由于node的封装性较低,node可以操作很多较为低级的操作,做路由,代理,解析头是相当方便,再加他不错的执行效率,我觉得用node做一些计算密集和I/O密集的方面还是很不错的.下面就是工作中遇到的,要判定用户坐标是否在市区的一个API,使用了判定点是否在多边形内的算法,大概思想是对每条边,判断点与这条边起始点与测试点的矢量A,这条边顺时针方向的法矢量B,测定AB夹角,如果是锐角,说明在顺时针这一边,那么如果对所有边测试点都在同一边,那么他就是在此多边形内.要求多边形数据是凸多边形.代码:

//Import libraries
var fs = require('fs');
var http = require('http');
var url = require('url');

//To accelerate,save data in memory
var cityCenterAreas = [];

//Util functions
function Point(x,y)
{
	return {x:x,y:y};
}

function Vector(p1,p2)
{
	return {x:p2.x-p1.x,y:p2.y-p1.y};
}

function getNormalVector(v)
{
	return {x:v.y,y:-v.x};
}

function dotMetrix(v1,v2)
{
	return v1.x*v2.x + v1.y*v2.y;
}

function isInCloseWiseSide(checkPoint,vectorStart,vectorEnd)
{
	var edge = Vector(vectorStart,vectorEnd);
	var test = Vector(vectorStart,checkPoint);
	var normalEgde = getNormalVector(edge);
	return dotMetrix(test,normalEgde) > 0;
}

function isAcceptedCity(cityId)
{
	return cityCenterAreas[cityId.toString()] != undefined;
}

/*
	Algorithm contributer:Needle
*/
	
function isCityCenter(cityId,x,y)
{
	if(!isAcceptedCity(cityId))return false;
	var testPoint = Point(parseFloat(x),parseFloat(y));
	cityId = cityId.toString();
	var cityPointsNum = cityCenterAreas[cityId].length;
	for(var i = 0;i < cityPointsNum;i++)
	{
		if(i != cityPointsNum - 1)
		{
			if(!isInCloseWiseSide(testPoint,cityCenterAreas[cityId][i],cityCenterAreas[cityId][i+1]))break;
		}
		else
		{
			if(!isInCloseWiseSide(testPoint,cityCenterAreas[cityId][i],cityCenterAreas[cityId][0]))break;
		}
	}
	return i == cityPointsNum;
}

//Load data from file
fs.readFile('data.json',function(err,data)
{
	if(err) throw err;
	cityCenterAreas = JSON.parse(data);
	//Data ready and start server
	http.createServer(function(request,response)
	{
		var getParams = url.parse(request.url,true).query;
		if(getParams.cityId == undefined || getParams.longitude == undefined || getParams.latitude == undefined)
		{
			response.writeHead(200,"Ok",{'Content-Type':'application/json'});
			response.end(JSON.stringify({code:"-1",msg:"Params missing!"}));
		}
		else
		{
			var body = "";
			response.writeHead(200,"Ok",{'Content-Type':'application/json'});
			if(isCityCenter(getParams.cityId,getParams.longitude,getParams.latitude))
			{
				body = "true";
			}
			else
			{
				body = "false"
			}
			response.end(JSON.stringify({code:"0",msg:"Request OK!",body:body}));
		}
	}).listen(8888);
});


数据文件data.json 储存了多个城市市区的边界点:

{
	"3":[{"x":120.205558,"y":30.389502},
		 {"x":120.277506,"y":30.353748},
		 {"x":120.340954,"y":30.328548},
		 {"x":120.369103,"y":30.248793},
		 {"x":120.229258,"y":30.10217},
		 {"x":120.152775,"y":30.127811},
		 {"x":120.113133,"y":30.140023},
		 {"x":120.065961,"y":30.212971},
		 {"x":120.052015,"y":30.274715},
		 {"x":120.089742,"y":30.376214}],
	"2":[{"x":116.508855,"y":40.002653},
		 {"x":116.554975,"y":39.875276},
		 {"x":116.555488,"y":39.850388},
		 {"x":116.459083,"y":39.79315},
		 {"x":116.426467,"y":39.77228},
		 {"x":116.282473,"y":39.783381},
		 {"x":116.219807,"y":39.930934},
		 {"x":116.231881,"y":40.000832},
		 {"x":116.363346,"y":40.028867}],
	"1":[{"x":121.415521,"y":31.402529},
		 {"x":121.703582,"y":31.29301},
		 {"x":121.785719,"y":31.127397},
		 {"x":121.6654,"y":30.911909},
		 {"x":121.273467,"y":30.889172},
		 {"x":121.16374,"y":31.005578},
		 {"x":121.145331,"y":31.137435},
		 {"x":121.15206,"y":31.201511},
		 {"x":121.212999,"y":31.346972},
		 {"x":121.225924,"y":31.351814}],
	"4":[{"x":113.41212,"y":23.141401},
		 {"x":113.37996,"y":23.10377},
		 {"x":113.353711,"y":23.073766},
		 {"x":113.228603,"y":23.05616},
		 {"x":113.204727,"y":23.156197},
		 {"x":113.228603,"y":23.05616},
		 {"x":113.410747,"y":23.145397}]
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值