Jump to content

Pesquisa por latitude e longitude por códigos postais


Recommended Posts

Posted

Boas pessoal,

Tenho estado a tentar atualizar uns códigos postais cp4+cp3 com os dados referentes à latitude e longitude. Aqui no forum encontrei um post do Cusco, que disponibilizava todas as ferramentas. Tentei reproduzir os passos todos, mas ao associar as coordenadas gps, ele apenas pesquisa por CP4. No ficheiro final do Cusco as coordenadas também são referentes a CP4.. por alguma razão o código não consegue pesquisar por cp4-cp3.

Alguem me pode dar uma ajuda a tentar ver se o código pode ser melhorado?

Fonte: 

https://www.portugal-a-programar.pt/forums/topic/40363-lista-c%C3%B3digos-postais-com-latlng/

 

<?php
$mysqli = new mysqli('localhost', 'root', '', 'CTT');

$qry = "select distinct CP4, CP3 from codigosPostais where LONGITUDE = '' AND LATITUDE = '' order by CP4 asc, CP3 asc limit 2500";
$qid = $mysqli->query($qry);
if($qid->num_rows == 0){
	echo "No results in database to update\n";
	die();
}

while($row = $qid->fetch_object()){

	$geo = getGeo($row->CP4, $row->CP3);
	if(!isset($geo->lat)){
		echo "$row->CP4-$row->CP3|error|$geo\n";
		continue;
	}
	$updQry = "update codigosPostais SET LONGITUDE=$geo->lat, LATITUDE=$geo->lng WHERE CP4=$row->CP4 AND CP3='$row->CP3'";
	$updQid = $mysqli->query($updQry);
	$aff = $mysqli->affected_rows;
	echo "$row->CP4-$row->CP3|$aff\n";
	#die();
}



function getGeo($cp4, $cp3){
	#$url = "http://maps.googleapis.com/maps/api/geocode/json?address=$cp4-$cp3&sensor=false&components=country:PT";
	$url = "http://ditu.google.cn//maps/api/geocode/json?address=$cp4-$cp3&sensor=false&components=country:PT";

	/* IP CHANGING STUFF
	 *
	 * Uncomment this and the comment block a few lines below
	 * only if you understand what it does, and after reading
	 * changeIp() function comments
	 *

	$i = 0;
	if(!file_exists('/ramdrive/googleip.txt')){
		file_put_contents('/ramdrive/googleip.txt','10.100.100.15');
		$currentIp = '10.100.100.16';	// default IP
	}else{
		$currentIp = file_get_contents('/ramdrive/googleip.txt');
	}
	$opts = array(
		'socket' => array(
			'bindto' => "$currentIp:0",
		),
	);
	$context = stream_context_create($opts);
	again:
	$data = json_decode(file_get_contents($url,false,$context));
	*/

	$data = @file_get_contents($url,false);
	if($data == false){
		return "error fetching $url";
	}
	$data = json_decode($data);
	if($data->status == 'OVER_QUERY_LIMIT'){
		/* IP Changing stuff
		if($i > 6){
			die('OVER_QUERY_LIMIT');
		}
		$i++;
		$context = stream_context_create(changeIp());
		goto again:
		*/
		echo "Google returned over query limit\n";
		die();
	}
	//$geo = $data->results[0]->geometry->location;
	$maxKey = max(array_keys($data->results));
	$geo = $data->results[$maxKey]->geometry->location;

	return $geo;
}

function changeIp(){
	/*
	 * This will return context options for file_get_contents
	 * the following IP list will basically be bound by the router
	 * with a netmap rule, NATing to different external IP's
	 * thus, allowing to increase google's limit of 2500 requests
	 * per IP per day.
	 *
	 * IP List
	 *
	 * 10.100.101.10
	 * 192.168.3.210
	 * 192.168.3.211
	 * 192.168.3.212
	 * 192.168.3.213
	 * 192.168.3.214
	 */
	$lastIp = trim(file_get_contents('/ramdrive/googleip.txt'));        // get last
	$newIp = $lastIp; // in case for some reason it remains unchanged
	switch($lastIp){
		case '10.100.101.10':
		$newIp = '192.168.3.210';
		break;
		case '192.168.3.210':
		$newIp = '192.168.3.211';
		break;
		case '192.168.3.211':
		$newIp = '192.168.3.212';
		break;
		case '192.168.3.212':
		$newIp = '192.168.3.213';
		break;
		case '192.168.3.213':
		$newIp = '192.168.3.214';
		break;
		case '192.168.3.214':
		$newIp = '10.100.101.10';
		break;
	}
	file_put_contents('/ramdrive/googleip.txt',$newIp);
	$opts = array(
		'socket' => array(
			'bindto' => "$newIp:0",
		),
	);
	return $opts;
}

?>
Posted

ora bem

1º  referes que estás a usar algo que encontraste no fórum sem dar uma referencia (link) directo para o tópico em questão

2º não apresentas uma descrição do problema, mas sim a tua suposta análise dos resultados obtidos

3º apresentas um código em PHP no mínimo, estranho (ligações ao google na china e mudanças de IP)

IRC : sim, é algo que ainda existe >> #p@p
Posted

Já atualizei a fonte.

Basicamente este código de php vai a um api do google, através dos códigos postais portugueses (4+3 digitos), fazer uma pesquisa e recolher as coordenadas de latitude  e longitude. O cusco desenvolveu este código para que possamos atualizar uma base de dados mySQL com todos os dados. A questão é, quando executo esta página, parece que ele apenas pesquisa pelos primeiros 4 digitos, ignorando os restantes 3..

Posted
11 minutos atrás, HappyHippyHippo disse:

basta dois pedidos directos à API para verificar que o problema não é nesta.

logo, o que poderás fazer é ver directamente o resultado da chamada desse código manhoso a ver se realmente é nele que o problema se encontra

Ao executar o ficheiro, o output dos 7 números dos códigos postais é o correto, mas as coordenadas não.

Output:

2830-098|1|38.6118719 -9.0405249
2830-099|1|38.6118719 -9.0405249

Analisando os seguintes números: 2830-098

através de: http://ditu.google.cn//maps/api/geocode/json?address=2830-098&sensor=false&components=country:PT

eu queria que ele fosse buscar estas coordenadas de location (2830-098):

"formatted_address" : "2830-098 Barreiro, Portugal",
         "geometry" : {
            "location" : {
               "lat" : 38.65858610000001,
               "lng" : -9.062972

mas ele vai buscar estas (2830):

         "formatted_address" : "2830, Portugal",
         "geometry" : {

(...)

            },
            "location" : {
               "lat" : 38.6118719,
               "lng" : -9.040524899999999



 

Posted

o problema é que o parsing da resposta da google não faz sentido, está na escolha cega do +ultimo resultado

	//$geo = $data->results[0]->geometry->location;
	$maxKey = max(array_keys($data->results));
	$geo = $data->results[$maxKey]->geometry->location;

deverias pesquisar a lsita de resultados e obter aquele que não retorna o parâmetro "partial_match" e/ou aquele que vem como tipo "postal_code_prefix"

  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Posted

Olá HappyHippyHippo

 

Obrigado desde já pelo input.

 

Estás a dizer que o script deve tentar obter aquele que não tiver partial_mathc, e/ou nao tiver postal_code_prefix - certo?

Sinceramente fiz a busca cega ao ultimo, porque em alguns casos de exemplo parecia-me o mais acertado - se tiveres melhor sugestão avisa, mas vou então implementar essa escolha no script :-)

 

Em 17/10/2016 às 13:04, HappyHippyHippo disse:

o problema é que o parsing da resposta da google não faz sentido, está na escolha cega do +ultimo resultado


	//$geo = $data->results[0]->geometry->location;
	$maxKey = max(array_keys($data->results));
	$geo = $data->results[$maxKey]->geometry->location;

deverias pesquisar a lsita de resultados e obter aquele que não retorna o parâmetro "partial_match" e/ou aquele que vem como tipo "postal_code_prefix"

Posted
Em 17/10/2016 às 12:52, fauves disse:

Ao executar o ficheiro, o output dos 7 números dos códigos postais é o correto, mas as coordenadas não.

Output:


2830-098|1|38.6118719 -9.0405249
2830-099|1|38.6118719 -9.0405249

Analisando os seguintes números: 2830-098

através de: http://ditu.google.cn//maps/api/geocode/json?address=2830-098&sensor=false&components=country:PT

eu queria que ele fosse buscar estas coordenadas de location (2830-098):


"formatted_address" : "2830-098 Barreiro, Portugal",
         "geometry" : {
            "location" : {
               "lat" : 38.65858610000001,
               "lng" : -9.062972

mas ele vai buscar estas (2830):


         "formatted_address" : "2830, Portugal",
         "geometry" : {

(...)

            },
            "location" : {
               "lat" : 38.6118719,
               "lng" : -9.040524899999999



 

Olá fauves

Alterei o ficheiro updateGeo.php no github, faz checkout e testa novamente, vê se está melhor 🙂

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.