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}]
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章