Оптимизация процесса поиска нарушителей земельного законодательства

в 7:43, , рубрики: python, оптимизация, проверка теории

Добрый день!

Давно мечтал внести свою лепту в этот замечательный проект, который читаю уже несколько лет.

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

Суть идеи заключается в том, что есть земельные участки на которых можно строить только частные жилые дома (Индивидуальное жилое строительство), и при этом запрещается использовать эти помещения для коммерческой деятельности. Хотя в России это никого не останавливало, и получается, что сотрудники должны ходить и проверять, что дом построен как жилой, а используется как ларек. В итоге ходить нужно долго и много плюс постоянно нужен доступ к информации для уточнения что же это за дом. Ну или же в офисе выбирать адреса для проверки и потом запрячь верблюдов, пополнить запасы воды и отправляться в удивительное путешествие.

Так как у нас в СМИ говорят что якобы цифровая экономика на дворе и вообще интернет вещей. То подход в виде посмотри в базе и иди погуляй как-то смотрится странно.

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

Позже по каждому кварталу были получены все объекты в его границах. Проблема появилась на этапе анализа данных, что координаты объектов даны в формате merсator P3857, пришлось добавлять перевод в привычную систему координат с долготой и широтой. Координаты объекта даются в двух видах, это точный центр участка и крайние точки общей геометрии участка.

json данные

"center": {
"x": 5135333.187724394,
"y": 6709637.473119974
},
"extent": {
"xmax": 5135346.924914406,
"xmin": 5135320.375756669,
"ymax": 6709666.568613776,
"ymin": 6709611.5618947
}

Первые координаты после перевода я использовал для тепловой карты. Пока возился с картой в QGIS (который я видел первый раз) пришла шальная идея что в популярных сервисах Яндекс карты и 2Гис можно искать объекты по координатам. Сразу же решил проверить данную теорию. И правда, если вбить координаты, то оба сервиса предоставляют информацию о данном доме. Следовательно напрашивается вывод, если отобрать объекты с характеристиками только под жилое строительство, и проверить их через данные об организациях, в случае если карты возвращали список организаций, то данное строение используется не по целевому назначению.

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

Для получения данных от карт использовал туповатый скрипт на Python (сразу извиняюсь? если этим кодом обидел программистов):

код

import requests
import json
import time
import csv
import pyproj
from random import choice
from random import randint
from pandas import read_csv

def get_proxy():
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 8; WOW32; rv:54.0) Gecko/20100101 Firefox/54.0'}
    proxies = open('proxy.txt').read().split('n')
    result=None
    proxy=""
    while result is None:
        try:
            proxy = {'http':'http://'+choice(proxies)}
            r = requests.get('http://ya.ru',headers=headers, proxies=proxy,timeout=(60, 60))
            if r.status_code==200:
                result=proxy
        except:
             pass
    return proxy


def main():
    headers = {
            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Encoding':'gzip, deflate',
            'Accept-Language':'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
            'Cache-Control':'max-age=0',
            'Connection':'keep-alive',
            'Cookie':'_ym_uid=1495451406361935235; _ym_isad=1; topCities=43-2; _2gis_webapi_session=0faa6497-0004-47c5-86d8-3bf9677f972a; _2gis_webapi_user=7e256d33-4c6e-44ab-a219-efc71e2d330f',
            'DNT':'1',
            'Host':'catalog.api.2gis.ru',
            'Upgrade-Insecure-Requests':'1',
            'User-Agent':'Mozilla/5.0 (Windows NT 7; WOW32; rv:54.0) Gecko/20100101 Firefox/54.0',
            'X-Compress':'null'
            }

    print("start")
    csvfile = open('GetShopsByCoordinats.csv', 'a', newline='')
    fieldnames = ['id', 'x','y','shops','names']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=';', quotechar='|',)
    writer.writeheader()
    
    inputCSV = read_csv('for2GIS.csv', sep=';', skiprows=[0], header=None)
    for i in range (0,5):
        s= 'point='+str(inputCSV[1][i])+'%2C'+str(inputCSV[2][i])+'&fields=search_attributes%2Citems.links&key=rutnpt3272'
        print (s)
        with requests.Session() as session:
            r=session.get('https://catalog.api.2gis.ru/2.0/geo/search?'+s, headers=headers,timeout=(60, 60))
            JsonData = r.json()
        try:
            print(JsonData['result']['items'][0]['links']['branches']['count'])
            writer.writerow({'id': str(inputCSV[0][i]),'x': str(inputCSV[1][i]), 'y': str(inputCSV[2][i]), 'shops': JsonData['result']['items'][0]['links']['branches']['count'] })
        except:
            writer.writerow({'id': str(inputCSV[0][i]),'x': str(inputCSV[1][i]), 'y': str(inputCSV[2][i]), 'shops': 'none' })

        time.sleep(randint(1,3))
    
    csvfile.close()
    print ('fin')

if __name__=='__main__':
    main()

В итоге получился файл в котором отражены все проверяемые объекты с кадастровым номером и координатами центра участка и данными с сайта о количестве магазинов в данной точке. Сами названия и контактные данные были не нужны.

Банальный автофильт в экселе по столбцу с количеством магазинов более 0, и получаем список потенциальных нарушителей, нужно только пройтись по уже «проверенным» адреса.
В планах на будущее сделать поиск не по точке а в радиусе границ участка, вроде такая возможность есть в API. И если количество выявленных объектов будет достаточным, то можно даже сделать построитель оптимальных маршрутов и шаблоны актов проверки по имеющимся данным.

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

Касательно выгрузки данных, на загрузку, сейчас получен легальный API ключ.

Автор: Darkzenon

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js