собственно, сабж.
мне это нужно для того, чтобы при вводе в поле ввода высвечивалась подсказка с названиями географических объектов.
Вот содержимое скрипт-файла (прошу прощения за говнокод).
// file: scripts/yandexmaps.js
window.onload = function() {
document.getElementById("findGeoObject").onclick = onFindButton;
}
function onFindButton() {
var findedObjectName = document.getElementById("geoObjectName").value.trim();
if (findedObjectName.length === 0) {
alert("Enter Geo Object Name!");
} else {
findGeoObjectByName(findedObjectName);
}
};
ymaps.ready(onMapWasLoaded);
var COORDINATES_OF_CHEBOKSARY = [56.135458999986554, 47.23548400000002];
var yandexMap;
var DEFAULT_ZOOM = 11;
var linesForAutocomplete;
function onMapWasLoaded() {
yandexMap = new ymaps.Map('map', {
center: COORDINATES_OF_CHEBOKSARY,
zoom: DEFAULT_ZOOM,
behaviors: ['default', 'scrollZoom']
});
initAutocomplete();
}
function initAutocomplete() {
$("#geoObjectName").keyup(function() {
var contentOfCurrentInput = $("#geoObjectName").val().trim();
if (autocompleteAvailable(contentOfCurrentInput)) {
resetAutocomplete(contentOfCurrentInput);
} else {
disableAutocomplete();
}
});
}
function autocompleteAvailable(content) {
var MIN_LENGTH_FOR_AUTOCOMPLETE = 2;
return (content.length >= MIN_LENGTH_FOR_AUTOCOMPLETE);
}
function resetAutocomplete(content) {
var MAX_SIZE_OF_AUTOCOMPLETE = 5;
linesForAutocomplete = [];
ymaps.geocode(content, {results: MAX_SIZE_OF_AUTOCOMPLETE}).then(function (res) {
addFindedGeoObjects(res.geoObjects);
});
}
function addFindedGeoObjects(geoObjects) {
geoObjects.each(function(geoObject) {
var coordinates = geoObject.geometry.getCoordinates();
getGeoObjectNameComponentsByCoordinates(coordinates, function(nameComponents) {
linesForAutocomplete.push(nameComponents.reverse().join(', '));
$("#geoObjectName").autocomplete('option', {
source: linesForAutocomplete
});
});
});
}
function disableAutocomplete() {
$("#geoObjectName").autocomplete({
source: []
});
}
var placemarkMover = new PlacemarkMover();
function findGeoObjectByName(geoObjectName) {
ymaps.geocode(geoObjectName, {results: 1}).then(function (res) {
var center = res.geoObjects.get(0).geometry.getCoordinates();
yandexMap.setCenter(center, DEFAULT_ZOOM);
placemarkMover.movePlacemark(center);
getGeoObjectNameComponentsByCoordinates(center, function(names) {
updateInfo(center, names.reverse().join(', '));
});
});
}
function getGeoObjectNameComponentsByCoordinates(coordinates, subsequentActions) {
ymaps.geocode(coordinates).then(function (res) {
var names = [];
res.geoObjects.each(function (obj) {
names.push(obj.properties.get('name'));
});
subsequentActions(names);
});
}
function updateInfo(coordinates, names) {
setText('info', names);
setText('location', 'Location: ' + coordinates[0] + ', ' + coordinates[1]);
}
function setText(id, text) {
document.getElementById(id).innerHTML = text;
}
function PlacemarkMover() {
var lastPlacemark = undefined;
return {
movePlacemark: function(coordinates) {
if (lastPlacemark !== undefined) {
yandexMap.geoObjects.remove(lastPlacemark);
}
lastPlacemark = new ymaps.Placemark(coordinates);
yandexMap.geoObjects.add(lastPlacemark);
}
}
}
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Поиск объектов на карте</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU"
type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles/styles.css" />
<script src="scripts/yandexmaps.js" type="text/javascript"></script>
</head>
<body>
<h2>Поиск объектов на Карте</h2>
<p>
<div class="ui-widget">
<input id="geoObjectName" />
<button id="findGeoObject">Find</button>
</div>
</p>
<div id="map"></div>
<div id="info"></div>
<div id="location"></div>
</body>
</html>
Код:
|
// file: styles/styles.css
#infoContainer {
background-color: rgb(243, 243, 243);
}
#map {
width: 600px;
height:300px;
} |
Собственно, проблема:
1) Находятся не все географические объекты, с заданной строкой.
2) Ищутся очень долго, заторможенно как-то.
3) Ищутся очень редко. Т.е. подсказка с результатами поиска появляется даже меньше, чем в 30% того, когда она должна появляться (в данном коде я задал, чтобы подсказка появлялась, если в поле введено не менее двух символов, это в функции autocompleteAvailable).
Возможно все эти проблемы связаны с тем, что я получаю содержимое будущей подсказки по-геморному. Сейчас я по строке получаю результат, содержащий geoObjects, в цикле прохожу все эти объекты, с каждым из них я проделываю: получаю координаты объекта, по координатам я
снова провожу поиск через Яндекс Карты, возвращается результат в котором есть поле с компонентами полного имени данного гео-объекта, эти компоненты в обратном порядке соединяю, вставляя между ними запятые. Наверное ничего не понятно. Но думаю понятно, что для данной задачи все эти действия избыточны. Может быть можно как-то проще, но другого способа не нашел. Кроме того, похоже, что у яндекс.карт в описании к API не всё освещено...
Заранее благодарю