Анализ и визуализация объектов с сайта объявлений на карте средствами Python и Leaflet.js​

Как лучше представить результаты проведенного анализа? Сегодня мы поделимся своим опытом.

По мере завершения анализа аналогов для арендуемых нами объектов на сайтах объявлений, перед нами стал вопрос - как лучше представить полученные результаты? Отчёты в документе или таблица в excel — выглядят довольно «сухо», так как не могут в полной мере отразить полученный результат и сформировать окончательное мнение. Поэтому используем интерактивную карту.

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

Для реализации такой интерактивности — было принято решение об использовании популярной javascript-библиотеки для работы с геоданными – leaflet.js.

Данные об арендуемых объектах и их аналогах среди объявлений в сети интернет необходимо обработать средствами python. Для предварительной обработки на вход подаётся excel-файл со следующими столбцами:

Далее, на основании полученного файла, средствами python будет формироваться json-объект, хранящий необходимые для работы библиотеки leaflet данные. Предварительно соберём информацию обо всех объектах, используя метод searchObjects:

def searchObjects(num_address,num_lat,num_lon,num_square,num_price,num_link=30,num_dist=31): wb = openpyxl.load_workbook(file_path) sheet = wb['Result'] addresses_list = [] json = {} for count in range(2,sheet.max_row+1): address = str((sheet.cell(row=count, column=num_address)).value) if address not in addresses_list: addresses_list.append(address) json[address] = {} json[address][“latitude”]=float((sheet.cell(row=count,column=num_lat)).value) json[address][“longtitude”] =float((sheet.cell(row=count,column=num_lon)).value) json[address][“square”] =float((sheet.cell(row=count,column=num_square)).value) json[address][“price”] =float((sheet.cell(row=count,column=num_price)).value) json[address][“neighbors”] =[] json[address][“link”] =float((sheet.cell(row=count,column=num_link)).value) json[address][“distance”] =float((sheet.cell(row=count,column=num_dist)).value) else: continue return json

Теперь, когда информация о необходимых объектах заполнена, необходимо произвести поиск объектов-аналогов для каждого из арендуемых объектов. Для этого предназначен метод searchNeighbors:

def searchNeighbors(self,addressesJson): wb = openpyxl.load_workbook(self.file_path) sheet = wb['Result'] for count in range(2,sheet.max_row+1): cell = sheet.cell(row=count, column=1) address = cell.value cell = sheet.cell(row=count,column=6) neighbor_address = cell.value addressesJson[address]["neighbors"].append(neighbor_address) return addressesJson

Метод, который объединяет в себе поиск информации об объектах и их аналогах и формирует файл, который в дальнейшем будет использован для визуализации:

def createJson(self): file = open("map.js","w",encoding="utf-8") json1 = self.searchObjects(1,2,3,5,4) json2 = self.searchObjects(6,7,8,10,9,11,12) json1.update(json2) resultJson = self.searchNeighbors(json1) file.write("objects="+str(resultJson)) file.close()

В результате данных манипуляций, получим js-файл, в котором будет находится json-объект данного формата:

Теперь можно приступить к дальнейшей разработке. Переходим на страницу библиотеки leaflet на вкладку Download и скачиваем актуальную версию библиотеки:

После этого создаём html страницу нашего итогового приложения и подключаем в нем эту библиотеку и js-файл с json – объектом, хранящим наши объекты в head – разделе:

<head> <meta charset="UTF-8"> <link rel="stylesheet" href="leaflet/leaflet.css" /> <script src="leaflet/leaflet.js"></script> <script src="map.js"></script> </head>

После этого в теле нашего html-файла создадим объект, в котором будет отображаться наша итоговая карта:

<div id="map"></div>

Для этого объекта указываем css – свойства: высоту и ширину окна

#map { width: 55%; height: 99%; }

Далее в коде, после нашего объекта, хранящего карту — разместим блок, в котором будем писать код на javascript для взаимодействия с картой:

<script type='text/javascript'> //код писать будем здесь </script>

Теперь в данном блоке напишем код, который будет отображать нашу карту:

var map = L.map('map').setView([47.222078, 39.720349], 13); L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a rel="nofollow" href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(map);

Метод setView в качестве параметров принимает в себя значение долготы и широты места, на котором будет центрироваться наша карта, а также величину зума, а с помощью L.tileLayer мы добавляем на нашу карту слой OpenStreetMap. Уже теперь можно посмотреть на первые результаты! Для этого запустим наш html-файл в браузере:

Теперь необходимо задать иконки, с помощью которых на нашей карте будут отображаться исследуемые объекты и создать слой, на котором будут отображаться объекты-аналоги:

var LeafIcon = L.Icon.extend({ options: {iconSize:[20, 25], iconAnchor:[10,25], popupAnchor:[0, 0]} }); // задаём иконку, с помощью которой будем отображать арендуемые объекты var neighborIcon = new LeafIcon({iconUrl: 'leaflet/neigh_baloon.png'}); // иконка объектов-аналогов var objectsN = L.layerGroup(); // задаём слой для отображения объектов-аналогов

Можно приступить к размещению на карте арендуемых объектов. Для этого из созданного и подключенного к нашему html файлу json-объекта будем собирать необходимую информацию с помощью следующего кода:

for (let key of Object.keys(objects)) { if (objects[key]["neighbors"].length!=0){ latitude = objects[key]["latitude"]; longtitude = objects[key]["longtitude"]; square = String(objects[key]["square"]); price = String(objects[key]["price"]) description="<strong>"+key+"</strong><p>"+square+" м<sup>2</sup></p><p>Цена: "+price+"</p>";//описание для popup маркера var marker = L.marker([latitude, longtitude],{icon: neighborIcon}); marker.on("click", object_popup_click); marker.properties = {object_address: key, object_square:square, object_price:price}; marker.addTo(map).bindPopup(description);}}

Строка marker.on(«click, object_popup_click) является обработчиком события и при нажатии на размещенный маркер будет запускать метод object_popup_click, который будет отображать объекты-аналоги, для этого добавим код этого метода в наш html-файл:

function object_popup_click(e){ try{objectsN.eachLayer(function(layer){map.removeLayer(layer);});} catch(err){console.log("Ошибка очистки значения");}//при ошибке выводим сообщение в консоль var object_latitude = e.latlng.lat; var object_longtitude = e.latlng.lng; var circle = L.circle([object_latitude,object_longtitude],{//создаём окружность для отрисоки color:'#00008B',fillColor:'#6495ED', fillOpacity: 0.5,radius: 1000}); objectsN.addLayer(circle).addTo(map);//добавляем окружность для рисования object_address = e.sourceTarget.properties["object_address"]; object_square = e.sourceTarget.properties["object_square"]; object_price = e.sourceTarget.properties["object_price"] neighbors = objects[object_address]["neighbors"]; neighbors_number = neighbors.length; for (var i=0; i<neighbors_number; i++){ data = objects[neighbors[i]]; link = "<a href=\""+data["link"]+"\"target=\"_blank\">Ссылка</a>" neighbor_description = "<strong>"+neighbors[i]+"</strong><p>"+data["square"]+" м<sup>2</sup></p><p>Цена:"+data["price"]+"</p>"+link+"<p>Расстояние:"+data["distance"]+"</p>"; neighbor_marker = L.marker([data["latitude"],data["longtitude"]]).bindPopup(neighbor_description); objectsN.addLayer(neighbor_marker).addTo(map);}}

Запускаем итоговое приложение и выбираем один из интересующих объектов:

Пробуем нажать на один из появившихся маркеров:

В итоге мы получили практические навыки по обработке данных на языке python и их дальнейшее отображение на карте с помощью javascript-библиотеки leaflet.js.

0
1 комментарий
Asf

В Избранное! Спасибо  !!!

Ответить
Развернуть ветку
-2 комментариев
Раскрывать всегда