⬆️ ⬇️

Geo-module for PHP applications

image The question “Where?” Arises immediately after the question “What?” This pattern is also true in web development. Many sites request information from the user, inviting him to enter his address, i.e., country, region, city, street, house zip code. But how then to process this data, if they were specified in a free form? In our first projects, we used our “bicycle”, but as it grew and developed, this “miracle” turned into a “monster”, which put an end to the efficient processing of geo-information about our users. I was given the task of nailing this monster, replacing it with a standardized geo-base and a simple interface for working with it. Googling on this topic did not give a ready-made solution, so I had to drop the simple option and make my own geo-module.



Base addresses Russia



To begin with, it was necessary to find the base of addresses of Russia In search of the address database, I came across two and it is quite possible that the only ones:

  1. KLADR (RF Address Classifier) ​​is distributed in * .dbf format
  2. FIAS (Federal Information Address System). By default, they will be distributed in the form of xml structure, but you still had to adjust to KLADR and, due to its archaism, FIAS also became distributed in dbf format


The difference between them is as follows: 400 MB KLADR versus 9 GB of FIAS — a significant, isn't it? For this, I definitely want to use FIAS , since it can be assumed in terms of volume that its data are more redundant, which is correspondingly better. But I didn’t work with FIAS . Requests on the address table were terribly long and neither the arrangement of the indexes nor the query optimization helped me, I also used MySQL 5.5



With KLADR, however, the work was formed, and as it turned out later, its details for my (standard) tasks are quite enough. A review of the structure of the KLADR tables, but you can read here / For him, someone made an api that does not work :-), but maybe the guys will finish, I think many would be useful.



In order to be able to use KLADR in the project, you need to convert it from the distributed dbf format into something understandable MySQL. However, you can fill the database directly, for this you can use navicat or mydbf2mysql .

')

Thus, I made a simple geo-module that can be screwed up for any needs.

The project is available on Github .



What is a module?



The project was written using php 5.3, which is important.

MySQL 5.5 DBMS, which is not very important.



Used libraries




File structure of the project
 .project # Project root
 -css \ 
 -js \
 --plugins
 --- autocomplete 
 ---- jquery.autocomplete.js
 --- jquery.form.js
 --cabinet.js # script for the page with the form
 --initialize.js # initialization script
 --jquery-1.7.2.js 
 -Entities \ 
 --GeoLocation.php # Entity with ip address location data
 --UserLocation.php # Entity with user location data
 --Kladr.php # Entity contains entries with objects of the first four levels of classification
 --Socrbase.php # Entity contains entries with short names for types of address objects
 --Street.php # Entity contains entries with objects of the fifth classification level
 --Doma.php # Entity contains entries with objects of the sixth level of classification
 --KladrRepository.php 
 --HomeRepository.php 
 --StreetRepository.php 
 -Geo \
 --Providers \
 --- Deliveries Shipping Providers 
 ---- Ems \ 
 ----- EmsDeliveryDecorator.php Class decorator calculating EMS delivery 
 ----- EmsDiliveryProvider.php # Class that implements the EMS service API for calculating delivery 
 ----- ENUM_EMS.php # command listing
 ---- RussianPost \ 
 ----- RussianPostDeliveryDecorator.php Class decorator for delivering Russian Post
 ----- RussianPostDeliveryProvider.php # Class that implements PostCalc service API for calculating delivery 
 --- Geocoder \ Geocoder service providers
 ---- Yandex \ 
 ----- Geocoder.php
 ---- MapApiBase.php # Abstract class for geocoding
 --- Delivery.php 
 --- DeliveryBase.php
 --- DeliveryDecoratorBase.php
 --- DeliveryDecoratorRound.php
 --- DeliveryProviderBase.php 
 --common.php
 --Geo.php
 --GoecoderCreater.php # Factory for a geocoding object
 --ILocationBuilder.php 
 --Location.php # class who can make requests to the geo-ip service
 --LocationBuilder.php # object builder \ Entities \ UserLocation, according to data received from the geocoder
 -_content.php 
 -autobox.php # entry point for plug-in requests for drop-down lists (orkug / city)
 -autocomlete.php # entry point for
 -Autoloader.php # my auto class loader
 -delivery.php # entry point for requests for the calculation of delivery
 -index.php # main entry point
 -popup.php # implementation example via modal popup window colorbox 
 -run.php # bootstrap example applications
 -String.php # string common static methods




Used api services




What we can




The process is as follows: when loading the page, we get to the ip address of the geo location of the user, for this we first look at whether there is an entry with a key (ip address) in the geoLocation table, if we take from there, if not, make a request to the ipGeo service we save the data in the plate geoLocation, for the subsequent reduction of query traffic in the ipgeo service. The available data on the location of the user is used to predict the location of the user, i.e. three (region / district / city) drop-down lists, fill with data and select the desired location in them. If the location is guessed correctly, then the user will only have to specify the street and the house, and the index (if it is in the clade) will be automatically substituted. However, if at the ip address the location was not guessed, then the region / district / city can be changed. For this was written piers js plug-in, which according to the selected region requests the district and large cities of the region, and according to the selected district, the city of the district.



There is a yandex map to display the user's saved location. However, you can make the map react on the fly to the choice of the location by the user.



At the end of the page with the address setting form, for demonstration there is a block with the delivery calculation. The delivery package itself is implemented as a “decorator”, so you can adjust the calculation of the amounts or the delivery time. Actually, how the calculation works, it should be clear, you need to know from where and where, and then the matter of technology. Delivery calculation can be expanded by adding a new * supplier *.



It is fortunate that the structure of specifying FIAS addresses is similar to KLADR, please note that it is not identical, but therefore it’s similar if you refactor the \ Entities \ KadrRepository repository code a little, then FIAS can be used as a repository of addresses, the only question is whether this is necessary.



I publish a detailed description of the API module in WiKi on github



I hope that this module will be useful to someone, but I do not pretend to be the perfect solution, I will be glad to hear comments and suggestions.

Source: https://habr.com/ru/post/150015/



All Articles