├── CTT.sql ├── CTT_postcodes_w_lat_lng.zip ├── README.md ├── bar.php ├── codigosPostais_WIP.sql ├── ctt-lat-lng-csv.zip ├── external ├── concelhos.txt ├── distritos.txt ├── leiame.txt └── todos_cp.txt ├── get-geocode.php ├── import.php ├── schema.sql ├── todos_cp_20190426.zip └── updateGeo.php /CTT_postcodes_w_lat_lng.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/CTT_postcodes_w_lat_lng.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CTT database with Lat Lng 2 | === 3 | 4 | #### update: upon much requested, added a csv export: https://github.com/cusco/ctt/raw/master/ctt-lat-lng-csv.zip 5 | #### this file already has the scanned address and found address viaq google. 6 | ___ 7 | 8 | ctt postal codes into MySQL with latitude and longitude from google 9 | 10 | 11 | external - files downloaded from CTT ( http://www.ctt.pt/feapl_2/app/restricted/postalCodeSearch/feapl_2_31-postalCodeDownloadFiles.jspx ) 12 | 13 | basically: 14 | - download files from http://www.ctt.pt/feapl_2/app/restricted/postalCodeSearch/feapl_2_31-postalCodeDownloadFiles.jspx 15 | - put them in the folder external 16 | - create database, user, password in MySQL 17 | - change user/password in import.php and getGeo.php 18 | - run php -q import.php 19 | - run php -q updateGeo.php (this is slow.. and is restricted to 2500 (google limit per day?)) 20 | 21 | updateGeo.php uses google to get latitude and longitude. 22 | 23 | Google has some daily usage restrictions .. 24 | There is a piece of code commented to use a different IP when the limit is reached (in my case I have several internal IP's on the operating system, that will be NAT'ed to different public IP's) 25 | 26 | You will have to run getGeo.php several times until your table is populated, or remove the initial select limit. 27 | 28 | 29 | *new* - added file CTT.sql which contains structure and data generated from these scripts. This is probably what everybody wants. 30 | 31 | *new* - updated CTT.sql with new latitudes and longitudes based on feedback from: http://www.portugal-a-programar.pt/forums/topic/74313-pesquisa-por-latitude-e-longitude-por-c%C3%B3digos-postais/?do=findComment&comment=599669 32 | -------------------------------------------------------------------------------- /bar.php: -------------------------------------------------------------------------------- 1 | 38 | * for($x=1;$x<=100;$x++){ 39 | * 40 | * show_status($x, 100); 41 | * 42 | * usleep(100000); 43 | * 44 | * } 45 | * 46 | * 47 | * @param int $done how many items are completed 48 | * @param int $total how many items are to be done total 49 | * @param int $size optional size of the status bar 50 | * @return void 51 | * 52 | */ 53 | 54 | function show_status($done, $total, $size=30) { 55 | if($done == 0) 56 | $done = 1; 57 | static $start_time; 58 | // if we go over our bound, just ignore it 59 | if($done > $total) return; 60 | 61 | if(empty($start_time)) $start_time=time(); 62 | $now = time(); 63 | 64 | $perc=(double)($done/$total); 65 | 66 | $bar=floor($perc*$size); 67 | 68 | $status_bar="\r["; 69 | $status_bar.=str_repeat("=", $bar); 70 | if($bar<$size){ 71 | $status_bar.=">"; 72 | $status_bar.=str_repeat(" ", $size-$bar); 73 | } else { 74 | $status_bar.="="; 75 | } 76 | 77 | $disp=number_format($perc*100, 0); 78 | 79 | $status_bar.="] $disp% $done/$total"; 80 | 81 | $rate = ($now-$start_time)/$done; 82 | $left = $total - $done; 83 | $eta = round($rate * $left, 2); 84 | 85 | $elapsed = $now - $start_time; 86 | 87 | $status_bar.= " remaining: ".number_format($eta)." sec. elapsed: ".number_format($elapsed)." sec."; 88 | 89 | echo "$status_bar "; 90 | 91 | flush(); 92 | 93 | // when done, send a newline 94 | if($done == $total) { 95 | echo "\n"; 96 | } 97 | 98 | } 99 | 100 | ?> 101 | 102 | -------------------------------------------------------------------------------- /ctt-lat-lng-csv.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/ctt-lat-lng-csv.zip -------------------------------------------------------------------------------- /external/concelhos.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/external/concelhos.txt -------------------------------------------------------------------------------- /external/distritos.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/external/distritos.txt -------------------------------------------------------------------------------- /external/leiame.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/external/leiame.txt -------------------------------------------------------------------------------- /external/todos_cp.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/external/todos_cp.txt -------------------------------------------------------------------------------- /get-geocode.php: -------------------------------------------------------------------------------- 1 | array( 32 | 'bindto' => "$currentIp:0", 33 | ), 34 | ); 35 | $context = stream_context_create($opts); 36 | */ 37 | $debug = Array(); 38 | $i=0; 39 | again: 40 | 41 | 42 | /* Make HTTP Request to $url */ 43 | $timeTaken = microtime(true); 44 | #$feed = file_get_contents($url . "&key=$key", false, $context) or die("ERROR: Can't open $url"); 45 | $feed = file_get_contents($url, false) or die("ERROR: Can't open $url"); 46 | $debug["$i"] = (microtime(true) - $timeTaken); 47 | $obj = json_decode($feed); // Parse JSON 48 | 49 | // log debug 50 | #if($obj->{'status'} != "OK" ){ 51 | # $log = date('Y-m-d H:i:s') . "|$currentIp|" . $_SERVER['REMOTE_ADDR'] . '|' . $obj->{'status'} . '|' . $url . "&key=$key\n"; 52 | # file_put_contents( __DIR__ . '/logXpto.txt', $log, FILE_APPEND); 53 | #} 54 | 55 | if($obj->{'status'} == "OVER_QUERY_LIMIT" ){ 56 | 57 | //$log = date('Y-m-d H:i:s') . "|$currentIp|" . $_SERVER['REMOTE_ADDR'] . '|OVER_QUERY_LIMIT|' . $url . "&key=$key\n"; 58 | //file_put_contents( __DIR__ . '/logXpto.txt', $log, FILE_APPEND); 59 | if($i > 11){ 60 | #var_dump($debug); 61 | #var_dump($url . "&key=$key"); 62 | #die($obj->{'status'}); 63 | header('Content-Type: application/json'); 64 | echo "$feed"; 65 | die(); 66 | 67 | } 68 | $i++; 69 | /* 70 | * uncomment this to rotate IPs 71 | $chIp = changeIp(); 72 | 73 | $context = stream_context_create($chIp['opts']); 74 | $key = $chIp['key']; 75 | $currentIp = $chIp['opts']['socket']['bindto']; 76 | $currentIp = explode(':', $currentIp); 77 | $currentIp = $currentIp[0]; 78 | */ 79 | goto again; 80 | }; 81 | 82 | echo "$feed"; 83 | 84 | 85 | /* not used here, but useful 86 | * when we have several IPs 87 | * being NATed to public IPs 88 | */ 89 | function changeIp(){ 90 | /* 91 | * IP List 92 | * 93 | * 10.100.100.15 94 | * 10.100.100.16 95 | * 10.100.100.17 96 | * 10.100.100.18 97 | * 10.100.100.19 98 | * 10.100.100.61 99 | * 10.100.100.62 100 | * 10.100.100.63 101 | * 10.100.100.64 102 | */ 103 | $lastIp = trim(file_get_contents('/ramdrive/googleip.txt')); // get last 104 | $newIp = $lastIp; // in case for some reason it remains unchanged 105 | switch($lastIp){ 106 | case '10.100.100.15': 107 | $newIp = '10.100.100.16'; 108 | break; 109 | case '10.100.100.16': 110 | $newIp = '10.100.100.17'; 111 | break; 112 | case '10.100.100.17': 113 | $newIp = '10.100.100.18'; 114 | break; 115 | case '10.100.100.18': 116 | $newIp = '10.100.100.19'; 117 | break; 118 | case '10.100.100.19': 119 | $newIp = '10.100.100.61'; 120 | break; 121 | case '10.100.100.61': 122 | $newIp = '10.100.100.62'; 123 | break; 124 | case '10.100.100.62': 125 | $newIp = '10.100.100.63'; 126 | break; 127 | case '10.100.100.63': 128 | $newIp = '10.100.100.64'; 129 | break; 130 | case '10.100.100.64': 131 | $newIp = '10.100.100.15'; 132 | break; 133 | } 134 | file_put_contents('/ramdrive/googleip.txt',$newIp); 135 | $opts = array( 136 | 'socket' => array( 137 | 'bindto' => "$newIp:0", 138 | ), 139 | ); 140 | 141 | $key = getKey($newIp); 142 | 143 | $result = Array( 144 | 'opts' => $opts 145 | ,'key' => $key 146 | ); 147 | 148 | return $result; 149 | } 150 | 151 | // to associate a key to a IP 152 | function getKey($ip){ 153 | $list = Array( 154 | '10.100.100.15' => 'keyXSyDbNysK0K-0Qlx5xKUp123CDcSkBqW8Vm0' 155 | ,'10.100.100.16' => 'keyXSyDvDOimn12380qyToxGkguFXA9I8EC3ceE' 156 | ,'10.100.100.17' => 'keyXSyCK123U4qjZrGTxRWv0DCHJN2vIUQZRiaM' 157 | ,'10.100.100.18' => 'keyX123M5LWCrMtor9mfylh8ILDtqYT7N3wxCyc' 158 | ,'10.100.100.19' => 'keyXSyAWRJ4kn56LSAJot2HVezFIQLyGLLHXfXY' 159 | ,'10.100.100.61' => 'keyXSyCbX_pO8UU-NDgeKYfr4QDOEJ123n4qJ5I' 160 | ,'10.100.100.62' => 'keyXSyCk3rAXwK7NdxPF-n9aBRPsBEvXjC123yY' 161 | ,'10.100.100.63' => 'keyXSyBnUjX4ul5RzwDvwOW123seB9nF9KvZy0U' 162 | ,'10.100.100.64' => 'keyXSyCLdgTBxTH7tsp123XR42VwzpvAjOYezpU' 163 | 164 | ); 165 | 166 | $key = false; 167 | 168 | if(array_key_exists($ip, $list)){ 169 | $key = $list["$ip"]; 170 | } 171 | 172 | return $key; 173 | } 174 | 175 | ?> 176 | -------------------------------------------------------------------------------- /import.php: -------------------------------------------------------------------------------- 1 | query($insQry); 35 | if(!$qid){ 36 | var_dump($mysqli->error); 37 | }else{ 38 | var_dump($qid); 39 | } 40 | } 41 | 42 | function importConcelhos($fileName, $dbName, $tableName, $mysqli){ 43 | $concelhos = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 44 | 45 | $insQry = "INSERT INTO $dbName.$tableName (Codigo_Distrito, Codigo_Concelho, Designacao_Concelho) VALUES\n"; 46 | 47 | foreach($concelhos as $line){ 48 | $fields = explode(';', $line); 49 | $cod_d = $fields[0]; 50 | $cod_c = $fields[1]; 51 | $desig = $fields[2]; 52 | 53 | $insQry .= "('$cod_d', '$cod_c', '$desig'),\n"; 54 | } 55 | 56 | // remove last ,\n 57 | $insQry = substr($insQry,0,-2); 58 | 59 | // Insert 60 | $qid = $mysqli->query($insQry); 61 | if(!$qid){ 62 | var_dump($mysqli->error); 63 | }else{ 64 | var_dump($qid); 65 | } 66 | 67 | } 68 | 69 | 70 | function importCodigosPostais($fileName, $dbName, $tableName, $mysqli){ 71 | $codigosPostais = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 72 | $total = count($codigosPostais); 73 | 74 | $insQry = " 75 | INSERT INTO $dbName.$tableName ( 76 | Codigo_Distrito 77 | ,Codigo_Concelho 78 | ,Codigo_Localidade 79 | ,LOCALIDADE 80 | ,ART_COD 81 | ,ART_TIPO 82 | ,PRI_PREP 83 | ,ART_TITULO 84 | ,SEG_PREP 85 | ,ART_DESIG 86 | ,ART_LOCAL 87 | ,TROCO 88 | ,PORTA 89 | ,CLIENTE 90 | ,CP4 91 | ,CP3 92 | ,CPALF 93 | ) VALUES 94 | "; 95 | $initialInsQry = $insQry; 96 | 97 | foreach($codigosPostais as $key => $line){ 98 | $fields = explode(';', $line); 99 | 100 | $cod_di = $mysqli->real_escape_string($fields[0]); 101 | $cod_co = $mysqli->real_escape_string($fields[1]); 102 | $cod_lo = $mysqli->real_escape_string($fields[2]); 103 | $locali = $mysqli->real_escape_string($fields[3]); 104 | $art_co = $mysqli->real_escape_string($fields[4]); 105 | $art_ty = $mysqli->real_escape_string($fields[5]); 106 | $pri_pr = $mysqli->real_escape_string($fields[6]); 107 | $art_ti = $mysqli->real_escape_string($fields[7]); 108 | $seg_pr = $mysqli->real_escape_string($fields[8]); 109 | $art_de = $mysqli->real_escape_string($fields[9]); 110 | $art_lo = $mysqli->real_escape_string($fields[10]); 111 | $troco = $mysqli->real_escape_string($fields[11]); 112 | $porta = $mysqli->real_escape_string($fields[12]); 113 | $client = $mysqli->real_escape_string($fields[13]); 114 | $cp4 = $mysqli->real_escape_string($fields[14]); 115 | $cp3 = $mysqli->real_escape_string($fields[15]); 116 | $cpalf = $mysqli->real_escape_string($fields[16]); 117 | 118 | $insQry .= "( 119 | '$cod_di' 120 | ,'$cod_co' 121 | ,'$cod_lo' 122 | ,'$locali' 123 | ,'$art_co' 124 | ,'$art_ty' 125 | ,'$pri_pr' 126 | ,'$art_ti' 127 | ,'$seg_pr' 128 | ,'$art_de' 129 | ,'$art_lo' 130 | ,'$troco' 131 | ,'$porta' 132 | ,'$client' 133 | ,'$cp4' 134 | ,'$cp3' 135 | ,'$cpalf' 136 | ),\n"; 137 | 138 | // seek bar 139 | show_status($key, $total-1); 140 | 141 | if($key % 999 == 0 && $key > 1){ // proccess 900 at a time 142 | #echo "$key\n"; 143 | $insQry = substr($insQry,0,-2); 144 | $qid = $mysqli->query($insQry); 145 | if(!$qid){ 146 | var_dump($insQry); 147 | var_dump($mysqli->error); 148 | die(); 149 | }else{ 150 | # echo "$key|"; 151 | # var_dump($qid); 152 | } 153 | 154 | $insQry = $initialInsQry; 155 | } 156 | 157 | } 158 | 159 | 160 | // remove last ,\n 161 | $insQry = substr($insQry,0,-2); 162 | 163 | // Insert 164 | $qid = $mysqli->query($insQry); 165 | if(!$qid){ 166 | var_dump($mysqli->error); 167 | }else{ 168 | var_dump($qid); 169 | } 170 | 171 | } 172 | 173 | -------------------------------------------------------------------------------- /schema.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 5.5.33, for debian-linux-gnu (x86_64) 2 | -- 3 | -- Host: localhost Database: CTT 4 | -- ------------------------------------------------------ 5 | -- Server version 5.5.33-1-log 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `codigosPostais` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `codigosPostais`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!40101 SET character_set_client = utf8 */; 25 | CREATE TABLE `codigosPostais` ( 26 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 27 | `Codigo_Distrito` char(2) NOT NULL, 28 | `Codigo_Concelho` char(2) NOT NULL, 29 | `Codigo_Localidade` int(11) DEFAULT NULL, 30 | `LOCALIDADE` varchar(96) NOT NULL, 31 | `ART_COD` varchar(96) NOT NULL, 32 | `ART_TIPO` varchar(96) NOT NULL, 33 | `PRI_PREP` varchar(96) NOT NULL, 34 | `ART_TITULO` varchar(96) NOT NULL, 35 | `SEG_PREP` varchar(96) NOT NULL, 36 | `ART_DESIG` varchar(96) NOT NULL, 37 | `ART_LOCAL` varchar(96) NOT NULL, 38 | `TROCO` varchar(96) NOT NULL, 39 | `PORTA` varchar(96) NOT NULL, 40 | `CLIENTE` varchar(96) NOT NULL, 41 | `CP4` mediumint(9) NOT NULL, 42 | `CP3` char(3) NOT NULL, 43 | `CPALF` varchar(96) NOT NULL, 44 | `LATITUDE` double NOT NULL, 45 | `LONGITUDE` double NOT NULL, 46 | PRIMARY KEY (`id`), 47 | KEY `Codigo_Distrito` (`Codigo_Distrito`), 48 | KEY `Codigo_Concelho` (`Codigo_Concelho`), 49 | KEY `Codigo_Localidade` (`Codigo_Localidade`), 50 | CONSTRAINT `codigosPostais_ibfk_1` FOREIGN KEY (`Codigo_Distrito`) REFERENCES `distritos` (`Codigo_Distrito`), 51 | CONSTRAINT `codigosPostais_ibfk_2` FOREIGN KEY (`Codigo_Concelho`) REFERENCES `concelhos` (`Codigo_Concelho`) 52 | ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; 53 | /*!40101 SET character_set_client = @saved_cs_client */; 54 | 55 | -- 56 | -- Table structure for table `concelhos` 57 | -- 58 | 59 | DROP TABLE IF EXISTS `concelhos`; 60 | /*!40101 SET @saved_cs_client = @@character_set_client */; 61 | /*!40101 SET character_set_client = utf8 */; 62 | CREATE TABLE `concelhos` ( 63 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 64 | `Codigo_Distrito` char(2) NOT NULL, 65 | `Codigo_Concelho` char(2) NOT NULL, 66 | `Designacao_Concelho` varchar(96) NOT NULL, 67 | PRIMARY KEY (`id`), 68 | KEY `Codigo_Distrito` (`Codigo_Distrito`), 69 | KEY `Codigo_Concelho` (`Codigo_Concelho`), 70 | CONSTRAINT `concelhos_ibfk_1` FOREIGN KEY (`Codigo_Distrito`) REFERENCES `distritos` (`Codigo_Distrito`) 71 | ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; 72 | /*!40101 SET character_set_client = @saved_cs_client */; 73 | 74 | -- 75 | -- Table structure for table `distritos` 76 | -- 77 | 78 | DROP TABLE IF EXISTS `distritos`; 79 | /*!40101 SET @saved_cs_client = @@character_set_client */; 80 | /*!40101 SET character_set_client = utf8 */; 81 | CREATE TABLE `distritos` ( 82 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 83 | `Codigo_Distrito` char(2) NOT NULL, 84 | `Designacao_Distrito` varchar(96) NOT NULL, 85 | PRIMARY KEY (`id`), 86 | UNIQUE KEY `Codigo_Distrito` (`Codigo_Distrito`) 87 | ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; 88 | /*!40101 SET character_set_client = @saved_cs_client */; 89 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 90 | 91 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 92 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 93 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 94 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 95 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 96 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 97 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 98 | 99 | -- Dump completed on 2014-02-24 12:15:04 100 | -------------------------------------------------------------------------------- /todos_cp_20190426.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cusco/ctt/d9be7c57295e8cce0836eb2b9250c7e9b7b8ac59/todos_cp_20190426.zip -------------------------------------------------------------------------------- /updateGeo.php: -------------------------------------------------------------------------------- 1 | query($qry); 9 | if($qid->num_rows == 0){ 10 | echo "No results in database to update\n"; 11 | die(); 12 | } 13 | 14 | while($row = $qid->fetch_object()){ 15 | 16 | $geo = getGeo($row->CP4, $row->CP3); 17 | if(!isset($geo->lat)){ 18 | echo "$row->CP4-$row->CP3|error|$geo\n"; 19 | continue; 20 | } 21 | $updQry = "update codigosPostais SET LONGITUDE=$geo->lat, LATITUDE=$geo->lng WHERE CP4=$row->CP4 AND CP3='$row->CP3'"; 22 | $updQid = $mysqli->query($updQry); 23 | $aff = $mysqli->affected_rows; 24 | echo "$row->CP4-$row->CP3|$aff\n"; 25 | #die(); 26 | } 27 | 28 | 29 | 30 | function getGeo($cp4, $cp3){ 31 | $url = "http://maps.googleapis.com/maps/api/geocode/json?address=$cp4-$cp3&sensor=false&components=country:PT"; 32 | #$url = "http://ditu.google.cn//maps/api/geocode/json?address=$cp4-$cp3&sensor=false&components=country:PT"; 33 | 34 | /* IP CHANGING STUFF 35 | * 36 | * Uncomment this and the comment block a few lines below 37 | * only if you understand what it does, and after reading 38 | * changeIp() function comments 39 | * 40 | 41 | $i = 0; 42 | if(!file_exists('/ramdrive/googleip.txt')){ 43 | file_put_contents('/ramdrive/googleip.txt','10.100.100.15'); 44 | $currentIp = '10.100.100.16'; // default IP 45 | }else{ 46 | $currentIp = file_get_contents('/ramdrive/googleip.txt'); 47 | } 48 | $opts = array( 49 | 'socket' => array( 50 | 'bindto' => "$currentIp:0", 51 | ), 52 | ); 53 | $context = stream_context_create($opts); 54 | again: 55 | $data = json_decode(file_get_contents($url,false,$context)); 56 | */ 57 | 58 | $data = @file_get_contents($url,false); 59 | if($data == false){ 60 | return "error fetching $url"; 61 | } 62 | $data = json_decode($data); 63 | if($data->status == 'OVER_QUERY_LIMIT'){ 64 | /* IP Changing stuff 65 | if($i > 6){ 66 | die('OVER_QUERY_LIMIT'); 67 | } 68 | $i++; 69 | $context = stream_context_create(changeIp()); 70 | goto again: 71 | */ 72 | echo "Google returned over query limit\n"; 73 | die(); 74 | } 75 | //$geo = $data->results[0]->geometry->location; 76 | $maxKey = max(array_keys($data->results)); 77 | $geo = $data->results[$maxKey]->geometry->location; 78 | 79 | foreach($data->results as $possibleResult){ // match best results according to http://www.portugal-a-programar.pt/forums/topic/74313-pesquisa-por-latitude-e-longitude-por-c%C3%B3digos-postais/#comment-599669 80 | 81 | if(substr($possibleResult->formatted_address,0,8)=="$cp4-$cp3"){ 82 | // preferable 83 | $geo = $possibleResult->geometry->location; 84 | break; 85 | } 86 | if(property_exists($possibleResult, 'partial_match')){ 87 | // avoid 88 | continue; 89 | } 90 | 91 | if(property_exists($possibleResult, 'types')){ 92 | if(in_array('postal_code_prefix', $possibleResult->types)){ 93 | // avoid 94 | continue; 95 | } 96 | } 97 | 98 | // not avoided (or broken) so far? use it!! 99 | $geo = $possibleResult->geometry->location; 100 | } 101 | return $geo; 102 | } 103 | 104 | function changeIp(){ 105 | /* 106 | * This will return context options for file_get_contents 107 | * the following IP list will basically be bound by the router 108 | * with a netmap rule, NATing to different external IP's 109 | * thus, allowing to increase google's limit of 2500 requests 110 | * per IP per day. 111 | * 112 | * IP List 113 | * 114 | * 10.100.101.10 115 | * 192.168.3.210 116 | * 192.168.3.211 117 | * 192.168.3.212 118 | * 192.168.3.213 119 | * 192.168.3.214 120 | */ 121 | $lastIp = trim(file_get_contents('/ramdrive/googleip.txt')); // get last 122 | $newIp = $lastIp; // in case for some reason it remains unchanged 123 | switch($lastIp){ 124 | case '10.100.101.10': 125 | $newIp = '192.168.3.210'; 126 | break; 127 | case '192.168.3.210': 128 | $newIp = '192.168.3.211'; 129 | break; 130 | case '192.168.3.211': 131 | $newIp = '192.168.3.212'; 132 | break; 133 | case '192.168.3.212': 134 | $newIp = '192.168.3.213'; 135 | break; 136 | case '192.168.3.213': 137 | $newIp = '192.168.3.214'; 138 | break; 139 | case '192.168.3.214': 140 | $newIp = '10.100.101.10'; 141 | break; 142 | } 143 | file_put_contents('/ramdrive/googleip.txt',$newIp); 144 | $opts = array( 145 | 'socket' => array( 146 | 'bindto' => "$newIp:0", 147 | ), 148 | ); 149 | return $opts; 150 | } 151 | 152 | ?> 153 | --------------------------------------------------------------------------------