Приятно когда живешь там где у тебя вход в метро в 15 минутах ходьбы и с комфортом жизни неплохо. Но кушать хочется всегда, а на рабочей неделе уж совсем нет времени и желания ехать в супермаркет чтобы сварить гречневую кашу и взять что-нибудь на завтрак. Магазины шаговой доступности есть везде, но мне хотелось бы чтобы это было что-нибудь более привычное, типа Пятёрочки, Дикси, Магнита, Перекрёстка, Магнолии, Атак или Ленты.

Жизнь по этому фактору в Серебряном бору( это один из победителей в категории удаленности от неблагоприятных факторов) отпадает сразу - там и до метро не близко! Найдем более удобные места для ежедневной жизни и похода в продуктовый магазин.

Это как в дилеме что первее: курица или яйцо, так же сетевой продуктовый/жилой район. Компании владельцы торговых сетей тратят деньги на геоанализ где им лучше расположить продуктовый магазин. Так что в каком-то виде мы переиспользуем их аналитику и найдем где живут мои соседи. Если же нужна другая группа соседей, то нужно поискать окрестности Азбуки Вкуса и бывшего Елисеевского.

Для анализа буду как обычно использовать геоданные OSM, и вот для выбора сетевых магазинов без "черной магии" мне не удастся обойтись, потому что в исходных данных полно опечаток, разных написаний и разношёрстности в обозначениях. После получаса экспериментов мне удалось подобрать нужное заклинание:

create temporary table supermarket_entrance as 
  select id, centre, tags 
    from geometry_global_view 
    where (tags@>'shop=>supermarket' or tags@>'shop=>convenience') and 
    		(tags->'brand' in ('Пятёрочка','ВкусВилл','Дикси','Магнит',
                               'Перекрёсток','Магнолия','Перекресток',
                               'Лента','Eurospar','Ашан','Супер Лента',
                               'Атак','СуперЛента','О’КЕЙ','Spar',
                               'Перекресток Экспресс','SPAR',
                               'METRO Cash & Carry','EuroSPAR','АТАК',
                               'Ашан Сити','Мини Лента','EUROSPAR',
                               'МиниЛента','METRO','Auchan','супер Лента') 
    		or tags@>'brand:wikipedia=>ru:Auchan');

Подробнее про подготовку данных к анализу можете почитать в прошлой статье. Чтобы исключить из геоанализа мавзолей на Красной площади и Кремлевские башни добавлю фильтр:not(b.tags?'tomb') and not(b.tags?'man_made') и найду жилые здания у интересующих магазинов:

explain create table living_building_near as
select m.id supermarket_entrance_id,st_x(m.centre) supermarket_entrance_x,st_y(m.centre) supermarket_entrance_y,
       array_agg((b.id,b.type,st_x(b.centre),st_y(b.centre))::building_info) buildings
  from supermarket_entrance m inner join geometry_global_view b on
    b.tags?'building' and
    not(b.tags?'amenity') and
    not(b.tags?'shop') and
    not(b.tags?'tomb') and
    not(b.tags?'man_made') and
    b.tags->'building' not in --в перечисленных ниже зданиях не живут на постоянной основе
        ('service','garages','industrial','retail','office','roof','commercial','garage','kiosk','warehouse','church',
        'parking','public','shed','hangar','train_station','guardhouse','transportation','terrace','greenhouse','bridge',
        'government','chapel','gazebo','civic','ruins','supermarket','sports_centre','semidetached_house','toilets',
        'sports_hall','clinic','farm_auxiliary','stable','grandstand','bunker','gatehouse','store','temple','ventilation_kiosk',
        'carport','cowshed','barracks','shop','cabin','barn','cathedral','wall','townhouse','manufacture','shelter',
        'fire_station','stadium','stands','sport_hall','theatre','storage_tank','checkpoint','houseboat','abandoned','dovecote',
        'mosque','museum','military','container','observatory','lift','tent','factory','sport','mall','riding_hall','depot',
        'prison','gate','triumphal_arch','water_works','public_building','pavilion','bank','institute','works','collapsed',
        'car_repair','crossing_box','fuel','tree_house','presbytery','yesq','farm','outbuilding','police','porch','sauna',
        'monastery','cinema','tower','boathouse','library','transformer_tower','heat_exchange_station','ice_rink','entrance','construction','transformer'
        ) and 
    ST_DWithin(b.geom::geography,m.centre::geography,500) 
  group by 1,2,3; -- create table living_building_near as select m.id supermarket_entrance_id,st_x(m.centre) supermarket_entrance_x,st_y(m.centre) supermarket_entrance_y,array_agg((b.id,b.type,st_x(b.centre),st_y(b.centre))::building_info) buildings from supermarket_entrance m inner join geometry_global_view b on b.tags?'_lb' and ST_DWithin(b.geom::geography,m.centre::geography,500) group by 1,2,3;

Посчитаю пешеходные расстояния от магазина до домов в радиусе 500м. Чтобы учесть случаи когда дом расположен через реку или автостраду без подземного перехода, не включать его в расчет расстояния.

GraphHopper 8 как движок расчета расстояний и Java код для него.
create table supermarket_distance(
                entrance_id bigint,
                building_id bigint,
                building_type table_reference,
                distance smallint,
                primary key(entrance_id,building_id,building_type)
);

Основная проблема с расчетом расстояний - это время вычислений, в случае если сервис взаимодействует с программой как REST через TCP добавляется round trip пакетов к времени обработки каждого запроса, поэтому буду использовать Graphhopper как библиотеку внутри процесса без вызовов по HTTP:

package com.github.isuhorukov.routing;

import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.GraphHopper;
import com.graphhopper.ResponsePath;
import com.graphhopper.config.CHProfile;
import com.graphhopper.config.Profile;
import org.postgresql.jdbc.PgArray;
import org.postgresql.util.PGobject;

import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Routing {

    public static final int MAX_DISTANCE = 500;

    public static void main(String[] args) throws Exception {
        GraphHopper hopper = getGraphHopper();
        try (Connection connection = DriverManager.getConnection(
                System.getenv("jdbc_url"), System.getenv("user"), System.getenv("password"))) {
            connection.setAutoCommit(false);
            try {
                var distances = calculateDistances(connection, hopper);
                saveDistance(connection, distances);
            } catch (SQLException e) {
                connection.rollback();
                throw e;
            }
        }
    }

    private static GraphHopper getGraphHopper() {
        var hopper = new GraphHopper();
        hopper.setOSMFile(System.getenv("osm_file"));
        hopper.setGraphHopperLocation("route");
        hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("foot"));
        hopper.setProfiles(new Profile("foot").setVehicle("foot"));
        hopper.importOrLoad();
        return hopper;
    }

    private static List<Distance> calculateDistances(Connection connection, GraphHopper hopper) throws SQLException {
        List<Distance> distances = new ArrayList<>();
        try (Statement supermarketQuery = connection.createStatement()){
            int step=0;
            try (ResultSet livingBuilding = supermarketQuery.executeQuery("select * from living_building_near")){
                while (livingBuilding.next()){
                    long supermarketEntranceId = livingBuilding.getLong("supermarket_entrance_id");
                    double supermarketEntranceX = livingBuilding.getDouble("supermarket_entrance_x");
                    double supermarketEntranceY = livingBuilding.getDouble("supermarket_entrance_y");
                    PgArray buildingsArray = (PgArray) livingBuilding.getArray("buildings");
                    List<Building> buildings = mapBuildings(buildingsArray);
                    System.out.println(step++);
                    distances.addAll(buildings.stream().map(building -> {
                        short distance = calculateDistances(hopper, building, supermarketEntranceY, supermarketEntranceX);
                        return new Distance(supermarketEntranceId,building.buildingId, building.buildingType, distance);
                    }).collect(Collectors.toList()));
                }
            }
        }
        return distances;
    }

    private static void saveDistance(Connection connection, List<Distance> distances) throws SQLException {
        try (PreparedStatement insert = connection.prepareStatement(
                "insert into supermarket_distance(entrance_id,building_id,building_type,distance) " +
                        "values (?,?,?::table_reference,?)")){
            distances.forEach(distance -> {
                if(distance.distance> MAX_DISTANCE) return;
                try {
                    insert.setLong(1, distance.supermarketEntranceId);
                    insert.setLong(2, distance.buildingId);
                    insert.setString(3, distance.buildingType);
                    insert.setShort(4, distance.distance);
                    insert.addBatch();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            });
            insert.executeBatch();
            connection.commit();
        }
    }

    private static List<Building> mapBuildings(PgArray buildingsArray) throws SQLException {
        return getPgObjects(buildingsArray).stream().map(pGobject -> {
            String value = pGobject.getValue();
            if(value==null || value.length()<=2){
                throw new IllegalArgumentException();
            }
            String[] parts = value.substring(1, value.length() - 1).split(",");
            long buildingId = Long.parseLong(parts[0]);
            String buildingType = parts[1];
            double buildingX = Double.parseDouble(parts[2]);
            double buildingY = Double.parseDouble(parts[3]);
            return new Building(buildingId, buildingType, buildingX, buildingY);
        }).collect(Collectors.toList());
    }

    private static List<PGobject> getPgObjects(PgArray buildingsArray) throws SQLException {
        Object[] array = (Object[]) buildingsArray.getArray();
        buildingsArray.free();
        return Arrays.stream(array).map(object -> (PGobject) object).collect(Collectors.toList());
    }

    private static short calculateDistances(GraphHopper hopper,
                                      Building building, double supermarketEntranceY, double supermarketEntranceX) {
        GHRequest request = new GHRequest(supermarketEntranceY, supermarketEntranceX, building.buildingY, building.buildingX);
        request.setProfile("foot");
        GHResponse route = hopper.route(request);
        if(route.hasErrors()){
            return Short.MAX_VALUE;
        }
        ResponsePath bestRoute = route.getBest();
        return (short) Math.round(bestRoute.getDistance());
    }

    private static class Building{
        long buildingId;
        String buildingType;
        double buildingX;
        double buildingY;
        public Building(long buildingId, String buildingType, double buildingX, double buildingY) {
            this.buildingId = buildingId;
            this.buildingType = buildingType;
            this.buildingX = buildingX;
            this.buildingY = buildingY;
        }
    }

    private static class Distance{
        long supermarketEntranceId;
        long buildingId;
        String buildingType;
        short distance;
        public Distance(long supermarketEntranceId, long buildingId, String buildingType, short distance) {
            this.supermarketEntranceId = supermarketEntranceId;
            this.buildingId = buildingId;
            this.buildingType = buildingType;
            this.distance = distance;
        }
    }
}
Карта домов в 500м у сетевых продуктовых магазинов шаговой доступности в Москве
Карта домов в 500м у сетевых продуктовых магазинов шаговой доступности в Москве

Выгружаю результат анализа в GeoJSON файл и отправляю его на GitHub:

\copy (select json_build_object('type', 'FeatureCollection','features', json_agg(json_build_object('type', 'Feature','geometry', st_AsGeoJSON(centre)::json))) from (select distinct centre from supermarket_distance s inner join geometry_global_view b on b.id=s.building_id and b.type=s.building_type) buildings ) to '~/moscow_supermarket_footpath.json';

Интересные находки

Подъезды в жилых домах в Москве часто не размечены на OpenStreetMap.

Зеленые дома - подъезд указан, "цвет-румянец" (#DE5D83) подъезды не указаны. И это еще неплохой процент разметки подъездов для столицы
Зеленые дома - подъезд указан, "цвет-румянец" (#DE5D83) подъезды не указаны. И это еще неплохой процент разметки подъездов для столицы

Можно было бы увеличить точность вычисления пешеходной дистанции к магазину, но сначала нужно разметить подъезды в исходных данных. И уже внес свою посильную помощь в геоданные Москвы по подъездам в жилых домах. Пообщался c местным сообществом мэпперов на эту тему и умные люди подсказали сайт, где желающие могут найти дома в которых не указаны подъезды и разметить их в OpenStreetMap.

В Москве для зданий иногда не хватает информации о его типе. Как заметили в коментариях к карте само здание магазина может быть учтено как жилое, например. В этом случае правильным решением будет изменить тип здания на building=retail и пересчитать карту. Я могу найти все такие здания и сформировать список, чтобы люди живущие в этом районе перепроверили и если здание действительно только с коммерческими объектами/магазином, обновили данные в OSM.

Здания в которых точкой указан магазин, но при этом у самого здания атрибут building=yes. Требуют проверки мэпперами и установки тега building в конкретный тип.

https://www.openstreetmap.org/way/100894391
https://www.openstreetmap.org/way/101520924
https://www.openstreetmap.org/way/101835431
https://www.openstreetmap.org/way/102258433
https://www.openstreetmap.org/way/103084977
https://www.openstreetmap.org/way/103267486
https://www.openstreetmap.org/way/104105383
https://www.openstreetmap.org/way/104708946
https://www.openstreetmap.org/way/105153309
https://www.openstreetmap.org/way/105223754
https://www.openstreetmap.org/way/106172667
https://www.openstreetmap.org/way/106182900
https://www.openstreetmap.org/way/106701710
https://www.openstreetmap.org/way/107423421
https://www.openstreetmap.org/way/107688695
https://www.openstreetmap.org/way/108219857
https://www.openstreetmap.org/way/108236482
https://www.openstreetmap.org/way/108680435
https://www.openstreetmap.org/way/108865980
https://www.openstreetmap.org/way/1104465315
https://www.openstreetmap.org/way/110687792
https://www.openstreetmap.org/way/111598880
https://www.openstreetmap.org/way/112427646
https://www.openstreetmap.org/way/112427654
https://www.openstreetmap.org/way/112957608
https://www.openstreetmap.org/way/1151175520
https://www.openstreetmap.org/way/1167128084
https://www.openstreetmap.org/way/118849541
https://www.openstreetmap.org/way/1199407091
https://www.openstreetmap.org/way/1212393299
https://www.openstreetmap.org/way/125135582
https://www.openstreetmap.org/way/125749299
https://www.openstreetmap.org/way/130998379
https://www.openstreetmap.org/way/133497863
https://www.openstreetmap.org/way/135403056
https://www.openstreetmap.org/way/136490012
https://www.openstreetmap.org/way/139758133
https://www.openstreetmap.org/way/139880858
https://www.openstreetmap.org/way/141643590
https://www.openstreetmap.org/way/144217655
https://www.openstreetmap.org/way/144431326
https://www.openstreetmap.org/way/144982569
https://www.openstreetmap.org/way/146844877
https://www.openstreetmap.org/way/146926413
https://www.openstreetmap.org/way/148175690
https://www.openstreetmap.org/way/149799585
https://www.openstreetmap.org/way/153479017
https://www.openstreetmap.org/way/154331592
https://www.openstreetmap.org/way/155713698
https://www.openstreetmap.org/way/157210001
https://www.openstreetmap.org/way/157210023
https://www.openstreetmap.org/way/157662338
https://www.openstreetmap.org/way/159169950
https://www.openstreetmap.org/way/160195738
https://www.openstreetmap.org/way/160283594
https://www.openstreetmap.org/way/160412231
https://www.openstreetmap.org/way/160624731
https://www.openstreetmap.org/way/160832465
https://www.openstreetmap.org/way/163552192
https://www.openstreetmap.org/way/167290047
https://www.openstreetmap.org/way/168771667
https://www.openstreetmap.org/way/168814799
https://www.openstreetmap.org/way/170022127
https://www.openstreetmap.org/way/173166370
https://www.openstreetmap.org/way/174292724
https://www.openstreetmap.org/way/177142544
https://www.openstreetmap.org/way/178407661
https://www.openstreetmap.org/way/179366388
https://www.openstreetmap.org/way/182693029
https://www.openstreetmap.org/way/182693031
https://www.openstreetmap.org/way/184818752
https://www.openstreetmap.org/way/187243722
https://www.openstreetmap.org/way/191318880
https://www.openstreetmap.org/way/193856609
https://www.openstreetmap.org/way/197891626
https://www.openstreetmap.org/way/204028854
https://www.openstreetmap.org/way/204059732
https://www.openstreetmap.org/way/215601988
https://www.openstreetmap.org/way/219036302
https://www.openstreetmap.org/way/220472244
https://www.openstreetmap.org/way/220566295
https://www.openstreetmap.org/way/23410660
https://www.openstreetmap.org/way/23414447
https://www.openstreetmap.org/way/234999243
https://www.openstreetmap.org/way/237391288
https://www.openstreetmap.org/way/238196235
https://www.openstreetmap.org/way/238312045
https://www.openstreetmap.org/way/24061473
https://www.openstreetmap.org/way/24147159
https://www.openstreetmap.org/way/241908928
https://www.openstreetmap.org/way/242025855
https://www.openstreetmap.org/way/24209522
https://www.openstreetmap.org/way/24241999
https://www.openstreetmap.org/way/244467206
https://www.openstreetmap.org/way/24507050
https://www.openstreetmap.org/way/24507115
https://www.openstreetmap.org/way/24611060
https://www.openstreetmap.org/way/24775828
https://www.openstreetmap.org/way/24812207
https://www.openstreetmap.org/way/248787400
https://www.openstreetmap.org/way/24919397
https://www.openstreetmap.org/way/250287690
https://www.openstreetmap.org/way/257074065
https://www.openstreetmap.org/way/258625152
https://www.openstreetmap.org/way/26232911
https://www.openstreetmap.org/way/26234186
https://www.openstreetmap.org/way/27117987
https://www.openstreetmap.org/way/271415296
https://www.openstreetmap.org/way/27474425
https://www.openstreetmap.org/way/27497492
https://www.openstreetmap.org/way/27506000
https://www.openstreetmap.org/way/27541227
https://www.openstreetmap.org/way/27541251
https://www.openstreetmap.org/way/27559430
https://www.openstreetmap.org/way/27559435
https://www.openstreetmap.org/way/27561120
https://www.openstreetmap.org/way/27566774
https://www.openstreetmap.org/way/27585064
https://www.openstreetmap.org/way/27644984
https://www.openstreetmap.org/way/27651221
https://www.openstreetmap.org/way/27652461
https://www.openstreetmap.org/way/27674678
https://www.openstreetmap.org/way/27704647
https://www.openstreetmap.org/way/27760428
https://www.openstreetmap.org/way/27761505
https://www.openstreetmap.org/way/27780732
https://www.openstreetmap.org/way/27787569
https://www.openstreetmap.org/way/27787772
https://www.openstreetmap.org/way/27793694
https://www.openstreetmap.org/way/27793759
https://www.openstreetmap.org/way/27804554
https://www.openstreetmap.org/way/27811019
https://www.openstreetmap.org/way/27811778
https://www.openstreetmap.org/way/27830650
https://www.openstreetmap.org/way/27867792
https://www.openstreetmap.org/way/27932029
https://www.openstreetmap.org/way/27937517
https://www.openstreetmap.org/way/28041162
https://www.openstreetmap.org/way/28041163
https://www.openstreetmap.org/way/28086033
https://www.openstreetmap.org/way/28086313
https://www.openstreetmap.org/way/28086933
https://www.openstreetmap.org/way/28159203
https://www.openstreetmap.org/way/281593080
https://www.openstreetmap.org/way/28187181
https://www.openstreetmap.org/way/28229589
https://www.openstreetmap.org/way/28260952
https://www.openstreetmap.org/way/28287387
https://www.openstreetmap.org/way/28288426
https://www.openstreetmap.org/way/28438624
https://www.openstreetmap.org/way/28438630
https://www.openstreetmap.org/way/28440144
https://www.openstreetmap.org/way/28443721
https://www.openstreetmap.org/way/28589281
https://www.openstreetmap.org/way/28682373
https://www.openstreetmap.org/way/28683352
https://www.openstreetmap.org/way/28813172
https://www.openstreetmap.org/way/28828653
https://www.openstreetmap.org/way/28859007
https://www.openstreetmap.org/way/28879157
https://www.openstreetmap.org/way/289119560
https://www.openstreetmap.org/way/28936655
https://www.openstreetmap.org/way/29103444
https://www.openstreetmap.org/way/29103472
https://www.openstreetmap.org/way/29103496
https://www.openstreetmap.org/way/29135249
https://www.openstreetmap.org/way/29157222
https://www.openstreetmap.org/way/29242569
https://www.openstreetmap.org/way/293852393
https://www.openstreetmap.org/way/29385861
https://www.openstreetmap.org/way/29386068
https://www.openstreetmap.org/way/29451041
https://www.openstreetmap.org/way/29463076
https://www.openstreetmap.org/way/29612046
https://www.openstreetmap.org/way/29689049
https://www.openstreetmap.org/way/29689051
https://www.openstreetmap.org/way/29857039
https://www.openstreetmap.org/way/29858613
https://www.openstreetmap.org/way/30053553
https://www.openstreetmap.org/way/30159630
https://www.openstreetmap.org/way/301874546
https://www.openstreetmap.org/way/30385887
https://www.openstreetmap.org/way/304192165
https://www.openstreetmap.org/way/30524803
https://www.openstreetmap.org/way/30799687
https://www.openstreetmap.org/way/30853282
https://www.openstreetmap.org/way/31064381
https://www.openstreetmap.org/way/31499550
https://www.openstreetmap.org/way/315490755
https://www.openstreetmap.org/way/319196601
https://www.openstreetmap.org/way/319517618
https://www.openstreetmap.org/way/32148686
https://www.openstreetmap.org/way/32203087
https://www.openstreetmap.org/way/32245759
https://www.openstreetmap.org/way/32281934
https://www.openstreetmap.org/way/32281946
https://www.openstreetmap.org/way/32285084
https://www.openstreetmap.org/way/32285085
https://www.openstreetmap.org/way/32285089
https://www.openstreetmap.org/way/32285093
https://www.openstreetmap.org/way/32285094
https://www.openstreetmap.org/way/32285112
https://www.openstreetmap.org/way/322897019
https://www.openstreetmap.org/way/326009064
https://www.openstreetmap.org/way/32634856
https://www.openstreetmap.org/way/32783706
https://www.openstreetmap.org/way/32868214
https://www.openstreetmap.org/way/329234391
https://www.openstreetmap.org/way/332910765
https://www.openstreetmap.org/way/333320835
https://www.openstreetmap.org/way/334253499
https://www.openstreetmap.org/way/33645390
https://www.openstreetmap.org/way/337175154
https://www.openstreetmap.org/way/337638349
https://www.openstreetmap.org/way/33873945
https://www.openstreetmap.org/way/340454317
https://www.openstreetmap.org/way/34319611
https://www.openstreetmap.org/way/34333989
https://www.openstreetmap.org/way/344121820
https://www.openstreetmap.org/way/34923909
https://www.openstreetmap.org/way/34944483
https://www.openstreetmap.org/way/34956213
https://www.openstreetmap.org/way/35094210
https://www.openstreetmap.org/way/35355247
https://www.openstreetmap.org/way/35550690
https://www.openstreetmap.org/way/35574543
https://www.openstreetmap.org/way/35766633
https://www.openstreetmap.org/way/35766634
https://www.openstreetmap.org/way/35766636
https://www.openstreetmap.org/way/35770361
https://www.openstreetmap.org/way/35902078
https://www.openstreetmap.org/way/359586245
https://www.openstreetmap.org/way/36945872
https://www.openstreetmap.org/way/37148025
https://www.openstreetmap.org/way/37647643
https://www.openstreetmap.org/way/37756905
https://www.openstreetmap.org/way/37769515
https://www.openstreetmap.org/way/37869501
https://www.openstreetmap.org/way/37934705
https://www.openstreetmap.org/way/379736242
https://www.openstreetmap.org/way/37974241
https://www.openstreetmap.org/way/380334763
https://www.openstreetmap.org/way/38344080
https://www.openstreetmap.org/way/38448827
https://www.openstreetmap.org/way/38449071
https://www.openstreetmap.org/way/38543715
https://www.openstreetmap.org/way/38582314
https://www.openstreetmap.org/way/385840818
https://www.openstreetmap.org/way/386472144
https://www.openstreetmap.org/way/391339151
https://www.openstreetmap.org/way/391735425
https://www.openstreetmap.org/way/391735552
https://www.openstreetmap.org/way/392791536
https://www.openstreetmap.org/way/39393747
https://www.openstreetmap.org/way/39574616
https://www.openstreetmap.org/way/39578457
https://www.openstreetmap.org/way/39623670
https://www.openstreetmap.org/way/39629325
https://www.openstreetmap.org/way/39752727
https://www.openstreetmap.org/way/39757585
https://www.openstreetmap.org/way/398987101
https://www.openstreetmap.org/way/39898904
https://www.openstreetmap.org/way/39898988
https://www.openstreetmap.org/way/39899010
https://www.openstreetmap.org/way/39963181
https://www.openstreetmap.org/way/40008963
https://www.openstreetmap.org/way/40032763
https://www.openstreetmap.org/way/40032776
https://www.openstreetmap.org/way/401514211
https://www.openstreetmap.org/way/401765048
https://www.openstreetmap.org/way/40522997
https://www.openstreetmap.org/way/40584290
https://www.openstreetmap.org/way/40595090
https://www.openstreetmap.org/way/40604742
https://www.openstreetmap.org/way/40678989
https://www.openstreetmap.org/way/40794061
https://www.openstreetmap.org/way/410016295
https://www.openstreetmap.org/way/41183725
https://www.openstreetmap.org/way/41183733
https://www.openstreetmap.org/way/41192263
https://www.openstreetmap.org/way/41276342
https://www.openstreetmap.org/way/41277272
https://www.openstreetmap.org/way/41278593
https://www.openstreetmap.org/way/41278612
https://www.openstreetmap.org/way/41278654
https://www.openstreetmap.org/way/41290810
https://www.openstreetmap.org/way/41863400
https://www.openstreetmap.org/way/41863404
https://www.openstreetmap.org/way/41864162
https://www.openstreetmap.org/way/41901385
https://www.openstreetmap.org/way/41902200
https://www.openstreetmap.org/way/41902378
https://www.openstreetmap.org/way/41921853
https://www.openstreetmap.org/way/41921856
https://www.openstreetmap.org/way/41930847
https://www.openstreetmap.org/way/41930848
https://www.openstreetmap.org/way/422536508
https://www.openstreetmap.org/way/42350244
https://www.openstreetmap.org/way/42367043
https://www.openstreetmap.org/way/42369857
https://www.openstreetmap.org/way/42369860
https://www.openstreetmap.org/way/42371474
https://www.openstreetmap.org/way/42371475
https://www.openstreetmap.org/way/42374853
https://www.openstreetmap.org/way/42382861
https://www.openstreetmap.org/way/42388872
https://www.openstreetmap.org/way/42391151
https://www.openstreetmap.org/way/42420057
https://www.openstreetmap.org/way/425775242
https://www.openstreetmap.org/way/42690788
https://www.openstreetmap.org/way/42714757
https://www.openstreetmap.org/way/428734106
https://www.openstreetmap.org/way/429724415
https://www.openstreetmap.org/way/43129156
https://www.openstreetmap.org/way/43197398
https://www.openstreetmap.org/way/433143928
https://www.openstreetmap.org/way/43513849
https://www.openstreetmap.org/way/435187810
https://www.openstreetmap.org/way/438260009
https://www.openstreetmap.org/way/43997202
https://www.openstreetmap.org/way/44146688
https://www.openstreetmap.org/way/44611390
https://www.openstreetmap.org/way/44611398
https://www.openstreetmap.org/way/45016931
https://www.openstreetmap.org/way/45098671
https://www.openstreetmap.org/way/45129985
https://www.openstreetmap.org/way/45418627
https://www.openstreetmap.org/way/454821735
https://www.openstreetmap.org/way/45487386
https://www.openstreetmap.org/way/45738962
https://www.openstreetmap.org/way/45738963
https://www.openstreetmap.org/way/45739232
https://www.openstreetmap.org/way/45739429
https://www.openstreetmap.org/way/45833488
https://www.openstreetmap.org/way/45895819
https://www.openstreetmap.org/way/45897482
https://www.openstreetmap.org/way/45980294
https://www.openstreetmap.org/way/45981045
https://www.openstreetmap.org/way/46414244
https://www.openstreetmap.org/way/46546760
https://www.openstreetmap.org/way/46548882
https://www.openstreetmap.org/way/46553541
https://www.openstreetmap.org/way/46553545
https://www.openstreetmap.org/way/46559834
https://www.openstreetmap.org/way/46582734
https://www.openstreetmap.org/way/46582754
https://www.openstreetmap.org/way/46657105
https://www.openstreetmap.org/way/46657110
https://www.openstreetmap.org/way/46657145
https://www.openstreetmap.org/way/46696082
https://www.openstreetmap.org/way/467671273
https://www.openstreetmap.org/way/46975926
https://www.openstreetmap.org/way/47272928
https://www.openstreetmap.org/way/475128253
https://www.openstreetmap.org/way/47514301
https://www.openstreetmap.org/way/47585234
https://www.openstreetmap.org/way/47670841
https://www.openstreetmap.org/way/479526210
https://www.openstreetmap.org/way/48050576
https://www.openstreetmap.org/way/48057992
https://www.openstreetmap.org/way/48123588
https://www.openstreetmap.org/way/48165298
https://www.openstreetmap.org/way/48174226
https://www.openstreetmap.org/way/48285711
https://www.openstreetmap.org/way/48346310
https://www.openstreetmap.org/way/48416112
https://www.openstreetmap.org/way/48580561
https://www.openstreetmap.org/way/48609800
https://www.openstreetmap.org/way/48672423
https://www.openstreetmap.org/way/48830826
https://www.openstreetmap.org/way/48892900
https://www.openstreetmap.org/way/48902981
https://www.openstreetmap.org/way/489048307
https://www.openstreetmap.org/way/49205861
https://www.openstreetmap.org/way/492993623
https://www.openstreetmap.org/way/498262784
https://www.openstreetmap.org/way/50120274
https://www.openstreetmap.org/way/50127962
https://www.openstreetmap.org/way/50219837
https://www.openstreetmap.org/way/50286159
https://www.openstreetmap.org/way/50286711
https://www.openstreetmap.org/way/503076897
https://www.openstreetmap.org/way/50343596
https://www.openstreetmap.org/way/503621086
https://www.openstreetmap.org/way/504004417
https://www.openstreetmap.org/way/50848891
https://www.openstreetmap.org/way/51239423
https://www.openstreetmap.org/way/51300151
https://www.openstreetmap.org/way/51551234
https://www.openstreetmap.org/way/51675639
https://www.openstreetmap.org/way/516807371
https://www.openstreetmap.org/way/51683345
https://www.openstreetmap.org/way/51683366
https://www.openstreetmap.org/way/51709767
https://www.openstreetmap.org/way/51709775
https://www.openstreetmap.org/way/52115992
https://www.openstreetmap.org/way/52152421
https://www.openstreetmap.org/way/52443959
https://www.openstreetmap.org/way/52476627
https://www.openstreetmap.org/way/52477326
https://www.openstreetmap.org/way/52521599
https://www.openstreetmap.org/way/52584114
https://www.openstreetmap.org/way/52697542
https://www.openstreetmap.org/way/52807149
https://www.openstreetmap.org/way/52816912
https://www.openstreetmap.org/way/52889910
https://www.openstreetmap.org/way/53038599
https://www.openstreetmap.org/way/53149447
https://www.openstreetmap.org/way/53336360
https://www.openstreetmap.org/way/534901709
https://www.openstreetmap.org/way/53735927
https://www.openstreetmap.org/way/53770232
https://www.openstreetmap.org/way/53816192
https://www.openstreetmap.org/way/53854140
https://www.openstreetmap.org/way/542781474
https://www.openstreetmap.org/way/54440045
https://www.openstreetmap.org/way/546559458
https://www.openstreetmap.org/way/547624718
https://www.openstreetmap.org/way/547653915
https://www.openstreetmap.org/way/547653916
https://www.openstreetmap.org/way/547905917
https://www.openstreetmap.org/way/54830057
https://www.openstreetmap.org/way/54830060
https://www.openstreetmap.org/way/54830069
https://www.openstreetmap.org/way/54830077
https://www.openstreetmap.org/way/54984216
https://www.openstreetmap.org/way/55974514
https://www.openstreetmap.org/way/56043045
https://www.openstreetmap.org/way/56141007
https://www.openstreetmap.org/way/56677787
https://www.openstreetmap.org/way/578427183
https://www.openstreetmap.org/way/581552884
https://www.openstreetmap.org/way/583308443
https://www.openstreetmap.org/way/58742211
https://www.openstreetmap.org/way/59617558
https://www.openstreetmap.org/way/607145096
https://www.openstreetmap.org/way/60903204
https://www.openstreetmap.org/way/61226037
https://www.openstreetmap.org/way/61597532
https://www.openstreetmap.org/way/620965410
https://www.openstreetmap.org/way/62116357
https://www.openstreetmap.org/way/62116358
https://www.openstreetmap.org/way/62798591
https://www.openstreetmap.org/way/63083250
https://www.openstreetmap.org/way/648080171
https://www.openstreetmap.org/way/651943013
https://www.openstreetmap.org/way/655254359
https://www.openstreetmap.org/way/658514433
https://www.openstreetmap.org/way/66412256
https://www.openstreetmap.org/way/66866521
https://www.openstreetmap.org/way/669402842
https://www.openstreetmap.org/way/685331940
https://www.openstreetmap.org/way/695789515
https://www.openstreetmap.org/way/698040665
https://www.openstreetmap.org/way/74156783
https://www.openstreetmap.org/way/744446910
https://www.openstreetmap.org/way/74489479
https://www.openstreetmap.org/way/750291748
https://www.openstreetmap.org/way/755444724
https://www.openstreetmap.org/way/76830533
https://www.openstreetmap.org/way/77888672
https://www.openstreetmap.org/way/779280121
https://www.openstreetmap.org/way/78047998
https://www.openstreetmap.org/way/785110848
https://www.openstreetmap.org/way/78518464
https://www.openstreetmap.org/way/785349416
https://www.openstreetmap.org/way/78542969
https://www.openstreetmap.org/way/787181735
https://www.openstreetmap.org/way/79561164
https://www.openstreetmap.org/way/796847088
https://www.openstreetmap.org/way/80499649
https://www.openstreetmap.org/way/805274109
https://www.openstreetmap.org/way/81239589
https://www.openstreetmap.org/way/81244481
https://www.openstreetmap.org/way/81251551
https://www.openstreetmap.org/way/81525884
https://www.openstreetmap.org/way/81526501
https://www.openstreetmap.org/way/81662540
https://www.openstreetmap.org/way/81662818
https://www.openstreetmap.org/way/81663120
https://www.openstreetmap.org/way/81947733
https://www.openstreetmap.org/way/81947738
https://www.openstreetmap.org/way/81947799
https://www.openstreetmap.org/way/82251808
https://www.openstreetmap.org/way/82799048
https://www.openstreetmap.org/way/82799049
https://www.openstreetmap.org/way/83257764
https://www.openstreetmap.org/way/83872644
https://www.openstreetmap.org/way/842061210
https://www.openstreetmap.org/way/84681646
https://www.openstreetmap.org/way/84982373
https://www.openstreetmap.org/way/85480360
https://www.openstreetmap.org/way/85827471
https://www.openstreetmap.org/way/86489380
https://www.openstreetmap.org/way/870853528
https://www.openstreetmap.org/way/87535017
https://www.openstreetmap.org/way/88097664
https://www.openstreetmap.org/way/88515884
https://www.openstreetmap.org/way/893311976
https://www.openstreetmap.org/way/89676901
https://www.openstreetmap.org/way/908849592
https://www.openstreetmap.org/way/91144632
https://www.openstreetmap.org/way/91215744
https://www.openstreetmap.org/way/91971114
https://www.openstreetmap.org/way/92159691
https://www.openstreetmap.org/way/92342648
https://www.openstreetmap.org/way/92809933
https://www.openstreetmap.org/way/92834981
https://www.openstreetmap.org/way/92927657
https://www.openstreetmap.org/way/92927666
https://www.openstreetmap.org/way/92930755
https://www.openstreetmap.org/way/92972723
https://www.openstreetmap.org/way/93781882
https://www.openstreetmap.org/way/93834587
https://www.openstreetmap.org/way/94190476
https://www.openstreetmap.org/way/94190484
https://www.openstreetmap.org/way/94338383
https://www.openstreetmap.org/way/94611626
https://www.openstreetmap.org/way/95062134
https://www.openstreetmap.org/way/95801792
https://www.openstreetmap.org/way/96110317
https://www.openstreetmap.org/way/96110595
https://www.openstreetmap.org/way/96300063
https://www.openstreetmap.org/way/96653508
https://www.openstreetmap.org/way/96832984
https://www.openstreetmap.org/way/96927395
https://www.openstreetmap.org/way/97191442
https://www.openstreetmap.org/way/972278103
https://www.openstreetmap.org/way/97263483
https://www.openstreetmap.org/way/97513491
https://www.openstreetmap.org/way/98599166
https://www.openstreetmap.org/way/98643989
https://www.openstreetmap.org/way/98712938
https://www.openstreetmap.org/way/98870180
https://www.openstreetmap.org/way/99249948

Исходные данные OpenStreetMap доступны каждому и по лицензии являются свободными. Не надо быть data science специалистом чтобы посчитать расстояния от магазинов до домов.

Результат геоаналитики

Готовую карту жилых домов Москвы в 500м от сетевых продуктовых магазинов вы можете посмотреть по ссылке на GitHub Gist. Где точки на карте обозначают центры жилых зданий в шаговой доступности от магазинов.

Используйте на здоровье, если вам при выборе места жительства хочется учесть и тоже нужно зайти вечером в ближайший сетевой продуктовый магазин у дома.

Случайная популярность или как работает пресса

А теперь пару слов как работают журналисты или кто-то заказал очернение этой публикации про работу с открытыми гео данными или это резюме от ChatGPT.

Помните мем: Ученые научились лечить рак?

В этом случае все произошло так же. Лента ру опубликовала статью про то что удобное не удобно. Интересно случайно или в этом есть цель обесценить мой труд? Оставлю скриншот:

И самое интересное ссылка ведет сразу на Github, избегая описания на Хабре... Сравните оригинал и новость!)

Комментарии (24)


  1. Earthsea
    01.11.2023 05:59
    +5

    Еще есть сервисы доставки продуктов, не знаю какие в Москве условия, но по крайней мере в моем регионе не дороже Магнита с Пятерочкой. Да и вообще кажется, что сейчас не менее важно чтобы рядом был не только продуктовый магазин, но и пункты выдачи популярных маркетплейсов и почта.


    1. igor_suhorukov Автор
      01.11.2023 05:59
      +3

      пункты выдачи популярных маркетплейсов и почта

      Отличное замечание! Это важный фактор.


    1. igor_suhorukov Автор
      01.11.2023 05:59
      +4

      Еще есть сервисы доставки продуктов, не знаю какие в Москве условия, но по крайней мере в моем регионе не дороже Магнита с Пятерочкой.

      Даже в эпоху ковидных ограничений не использовал. Можно заказывать готовые продукты, но не то что нужно выбирать и взвешивать. В фасовке может оказаться гнилая картошка, поврежденный лук, зелень не первой свежести это первый фактор. Второй - утечка моего адреса и телефона, как уже было с другими пользователями сервисов доставки.


    1. Dolios
      01.11.2023 05:59

      Я пробовал заказывать с доставкой мясо, рыбу, овощи. Привозят дрянь, которую я сам никогда в жизни не купил бы. А это 80% рациона. Правда Магниты с Пятерочками я тоже не посещаю, там в 90%+ я тоже из списка выше ничего не куплю, ибо качество отвратительное.


      1. StjarnornasFred
        01.11.2023 05:59

        Ну так нужно покупать продукты в заводской упаковке. Овощи и фрукты я покупаю сам в магазине, а мясные продукты - только обработанные: рыбное филе, котлеты, колбаски, наггетсы и т. д. - что не нужно мыть, чистить и вообще обрабатывать, просто фигакнул в сковороду или микроволновку и через 15 минут готово.


        1. Dolios
          01.11.2023 05:59

          Кому надо? Мы полуфабрикаты не едим, они невкусные. Магазинный фарш и котлеты, как по мне, можно использовать исключительно в качестве особо жестокого наказания за что-то.


  1. Eldest77
    01.11.2023 05:59

    Живу в южном бутово. Вы будете удивлены, но в локальных супермаркетах цены ниже, чем в сетевых, правда и выбор меньше. А так - доставки - наше все. Вкусвилл, Перекресток, доставляют все быстро и бесплатно И это не единственные доставки. Нафиг тратить время на поход в супермаркет? Единственное что я покупаю без доставки, мясо, и овощи, фрукты т.к. в сетевых супермаркетах эти позиции плохого качества, либо очень высокая цена. Тут рулят локальные магазинчики.


    1. StjarnornasFred
      01.11.2023 05:59

      Вкусвилл, Перекресток

      Ну естественно, это же сети, которые себя позиционируют как премиум-класс. Там и цены соответствующие. Пятёрочка хоть и эконом, но наглеет в последнее время. А вот в Магнит иногда зайти - так с учётом акций полцены относительно такого же набора покупок из Перекрёстка. Так что - себе дороже.


    1. igor_suhorukov Автор
      01.11.2023 05:59

      Я сознательно не включал обычные продуктовые магазины в аналитику, потому что они есть везде. А сетевые супермаркеты много вкладывают в геоаналитику по пешеходной доступности для потенциальных клиентов.


      1. sshikov
        01.11.2023 05:59

        Ну, на самом деле тут как с метро. Я бы не хотел бы жить рядом с Ашаном. Потому что возле соседнего со мной после открытия рядом метро теперь почти всегда толпы народу. В то же время, то что он находится в пешей доступности (несколько условной - 30 минут) это очень и очень приятно. Ну то есть тут наверное есть некий оптимум.

        потому что они есть везде

        Да не, не везде. У нас вот есть X5 и Вкусвил - и все. Ближайший Перекресток - остановка на метро. Старый район. Так исторически сложилось.


        1. igor_suhorukov Автор
          01.11.2023 05:59

          Спасибо за идею! Локально в SQL запросах можно написать почти все что душа пожелает. Но ты же понимаешь что такие вещи с предпочтениями и кастомизацией требуют веб приложения и базы данных а не статических выгрузок на Gist если делиться этим?


          1. sshikov
            01.11.2023 05:59

            Конечно. Я догадываюсь, что формат показа очень сильно ограничивает. Скажем, я очень широко использовал кастомные маркеры, вплоть до анимированных. А это значит куча javascrip-та. И REST. Зато красиво как )))


            1. igor_suhorukov Автор
              01.11.2023 05:59

              Это была попытка сравнить по функционалу и проработанности, как открытый FreeCAD и проприетарный Fusion 360... Результаты твоей работы же не отчуждаемы от организации?)


              1. sshikov
                01.11.2023 05:59

                Не, это был прототип, на коленке, и чисто на open source решениях. Скорее, они бессмысленны без меня, потому что прототип. Я просто к тому, что идея сделать кастомные маркеры - она может быть очень плодотворной.


                1. igor_suhorukov Автор
                  01.11.2023 05:59

                  Расскажи пожалуйста, мне интересно! Ты про интерактивную карту, по типу как делал раньше с возможностью кликов по маркерам?


                  1. sshikov
                    01.11.2023 05:59
                    +1

                    Ну там было принципиально несколько кейсов. Один - это маркер, который раскрывается в описание объекта. По сути - диалог, который прицеплен к определению маркера. Цели очевидны - в этой вот карте показать адрес дома, расстояние от метро или магазина, тип постройки и т.п. - все что может быть интересно. Второй случай - это маркер с диаграммами (как минимум я делал круговые), где click или hover по части диаграммы тоже раскрывает информацию. Это обычно кластерные маркеры, которые показывают обобщенную информацию о каком-то регионе, а не одном объекте. Можно очевидно и не раскрывать, а например скроллить или панорамировать карту куда-то.

                    Я делал на лифлете, и в итоге чего только не пришлось прикрутить. Начиная с javascript D3 и кончая SVG, и canvas. Но в целом наши эксперименты показали, что даже тривиальная анимация или кастомизация маркера или интерактив (разные маркеры для разных сетевых магазинов) дает +100 очков к визуальной привлекательности продукта.


                    1. igor_suhorukov Автор
                      01.11.2023 05:59

                      Понял! Круто!!!

                      Игрался с JS на другой задаче и там вылазило что удобно на компьютере не так удобно на смартфоне, а люди сейчас больше с мобильных устройств сидят. Для комерческого продукта такое конечно нужно делать!


                      1. sshikov
                        01.11.2023 05:59
                        +1

                        А, да, если речь о смартфоне - я не знаю ничего ) тут надо заново продумывать.


                      1. igor_suhorukov Автор
                        01.11.2023 05:59

                        У меня есть идеи что точно пригодится почти каждому кто отображает OSM данные что на компе, что на мобильном. В чем загвоздка - я не фронтэндер и не дизайнер. Если бы кто с нужными навыками подключился к Open Source движухе


    1. Dolios
      01.11.2023 05:59

      Единственное что я покупаю без доставки, мясо, и овощи, фрукты

      Т.е. 80%+ здорового рациона :)


  1. china
    01.11.2023 05:59

    А можно ли выложить в формате как тут https://igor-suhorukov.github.io/ ? Условно, чтобы плохие дома - красные, хорошие зеленые. А то сейчас вижу количество домов, но как посмотреть на карте именно какой район выбрать для жилья - не понимаю: как только масштаб меняю, то все дома просто объединяются в одну цифру. Хочется посмотреть на Москву с высоты птичьего полета и оценить где больше зеленого.


    1. igor_suhorukov Автор
      01.11.2023 05:59

      Добрый день! Можно, как найду тайл сервер соотвествующий законодателсьву РФ.


      1. Dolios
        01.11.2023 05:59

        А как сервер может не соответствовать законодательству РФ?


        1. redmanmale
          01.11.2023 05:59

          когда он показывает границы государства на юго-западе не так, как написано в законе