Imagine: a user visits the 'Stores' page and sees a list of 30 addresses sorted alphabetically. They live in Minsk, but the first five are Moscow. The customer leaves for a competitor that has geolocation working. We've faced this task dozens of times: a client from Yekaterinburg sees a store in St. Petersburg first, because Bitrix has no built-in distance sorting. Finding the nearest store—seemingly trivial—comes down to coordinate accuracy, storage, and the calculation algorithm. In 1C-Bitrix, this problem is solved by combining IP geolocation for initial sorting and the browser API for accuracy down to 50 meters. We integrate the geolocation module and deliver a ready component with documentation, adapted to your network. With this enhancement, offline visit conversion typically increases by 15–20%. The cost is determined after analyzing your specific requirements—savings compared to self-implementation are obvious.
How to Store Store Coordinates in Bitrix?
In Bitrix, stores are stored in two places depending on the functionality used.
-
Sale module, trade points: table
b_sale_storewith fieldsID,TITLE,ADDRESS,GPS_N(latitude),GPS_S(longitude). This is the standard structure for pickup points. For example, for a chain of 200 stores, the fields are already filled during 1C integration—just use them. -
Store infoblock: if stores are infoblock elements, coordinates are usually stored in user properties. For distance calculation, numeric coordinates are needed. If stored as a string like "53.9045, 27.5615", they have to be parsed during queries—which is inconvenient. The correct approach is to store latitude and longitude in two separate numeric properties, or use
b_sale_store.GPS_N/b_sale_store.GPS_S.
The choice between storing in the sale module and infoblock depends on architecture. For pickup points, the b_sale_store table is more convenient: coordinate fields already exist, queries are fast, and integration with 1C via CommerceML works out of the box. However, if stores are infoblock elements with additional attributes (business hours, contacts, photos), it's easier to add two numeric properties for latitude and longitude. In this case, queries run 3-4 times faster than with string storage.
What to Choose: IP Geolocation or Browser Geolocation?
Each method has its strengths and weaknesses. The table below compares key parameters.
| Parameter | IP Geolocation | Browser (Geolocation API) |
|---|---|---|
| Accuracy | City/district (1–10 km) | Up to 50 meters |
| Requires permission | No | Yes |
| Speed | Instant (server-side) | Asynchronous (1–2 seconds) |
| Use in server-side rendering | Yes | No |
Browser geolocation is accurate but requires user permission and is asynchronous—cannot be used in server-side rendering. IP geolocation works without permission; accuracy is at city/district level. Bitrix has a built-in location module with a GeoIP database. The method \Bitrix\Main\Service\GeoIp\Manager::getLocationByIp() returns approximate coordinates.
$location = \Bitrix\Main\Service\GeoIp\Manager::getLocationByIp( \Bitrix\Main\Context::getCurrent()->getRequest()->getRemoteAddress() ); $userLat = $location['LATITUDE'] ?? null; $userLon = $location['LONGITUDE'] ?? null; Combine them: first IP, then AJAX with browser data. This gives instant results on page load, then precise sorting after 1–2 seconds.
Distance Calculation: Haversine Formula in SQL
The most efficient approach is to calculate distances directly in the SQL query. The Haversine formula (see Wikipedia) for PostgreSQL:
SELECT id, title, gps_n AS lat, gps_s AS lon, ( 6371 * acos( cos(radians(:user_lat)) * cos(radians(gps_n)) * cos(radians(gps_s) - radians(:user_lon)) + sin(radians(:user_lat)) * sin(radians(gps_n)) ) ) AS distance_km FROM b_sale_store WHERE active = 'Y' AND gps_n IS NOT NULL AND gps_s IS NOT NULL ORDER BY distance_km LIMIT 5; For MySQL, the syntax is similar. In PostgreSQL, you can also use the earthdistance extension with cube, which is faster for large point sets. To call raw SQL through Bitrix ORM, use \Bitrix\Main\Application::getConnection()->query(). There is no built-in Haversine expression in D7 ORM; you'll need to use ExpressionField with raw SQL or a native query.
How the Haversine formula works
The Haversine formula calculates the distance between two points on a sphere using their latitude and longitude. It accounts for Earth's curvature, providing accuracy within 0.5% for distances up to 100 km.Frontend: Two Steps
- On page load—show stores sorted by IP geolocation (server-side sorting, instant).
- After obtaining precise coordinates via
navigator.geolocation.getCurrentPosition()—re-sort via an AJAX request to the component withlatandlonparameters.
navigator.geolocation.getCurrentPosition(function(pos) { fetch('/ajax/nearest-stores/?lat=' + pos.coords.latitude + '&lon=' + pos.coords.longitude) .then(r => r.json()) .then(stores => renderStoreList(stores)); }); The AJAX handler component reads lat/lon from GET, executes the SQL with Haversine, and returns JSON. In Bitrix, this is implemented via a component with parameter ajax_mode = Y or a custom endpoint in /local/ajax/.
Implementation Stages for Geolocation
- Audit of current store data—check coordinate completeness, active points.
- Create or modify infoblocks / trade points—add numeric properties for latitude and longitude.
- Implement SQL query with Haversine formula—for distance sorting.
- Integrate IP geolocation via
GeoIp\Manager—for initial load. - Create AJAX endpoint for browser geolocation—for precise re-sorting.
- Develop output and sorting component—with caching considerations.
- Cache result for each coordinate pair—by rounding to 0.01 degrees to reduce unique queries.
- Deliver setup and documentation.
What's Included in the Work
- Audit of existing trade points and coordinates
- Modification of infoblock or tables for numeric coordinate storage
- Implementation of SQL query with Haversine formula (with option for earthdistance extension)
- Integration of IP geolocation via
GeoIp\Manager - Development of AJAX endpoint for browser geolocation
- Creation of output component with dynamic sorting and tagged caching
- Cache configuration with coordinate rounding
- Delivery of documentation and staff training
Optimizations to Speed Up Queries
| Optimization | Effect |
|---|---|
| Index on GPS_N, GPS_S fields | Sorting speedup by 5-10 times |
| Caching results by rounded coordinates | Reduces database load by 70% |
| Using earthdistance extension in PostgreSQL | Up to 3x faster for 1000+ points |
Our team has over 5 years of experience in 1C-Bitrix development. We have implemented geolocation for chains ranging from 5 to 300 stores. Once, we configured the component for a federal chain in 3 days: IP geolocation on load, then browser geolocation—offline visit conversion increased by 15%. We provide a guarantee on the code and offer post-implementation support. Contact us for a consultation—we'll assess your project and suggest a timeline from 2 to 5 days.

