Клуб API Карт

Internet Explorer и 2.0

Пост в архиве.

Всем привет! 

Изучаю api.yandex для интеграции с 1С. В свою очередь 1С работает с HTML документами только посредством internet exlorer'а.

Я тестировала код на chrome. В нем и в мозилле все работало. В explorer (8 и 9) выпадает ошибка со ссылкой на то, что метод geocode не поддерживается.

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>Примеры. Размещение карты на странице.</title>

  <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/>

 

<script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>

         

<script type="text/javascript">

 

  var myMap;

  

  ymaps.ready(init);

  

function init () {

            myMap = new ymaps.Map("map", {

                    center: [55.76, 37.64],

                    zoom: 10

                })              

        }

 

function addPlacemarkOnMap(adress){

             var myGeocoder = ymaps.geocode(adress, {results: 1}).then(

function (res){

myMap.geoObjects.add(res.geoObjects);

},

function (err){

alert(err.message);

}

);

}

    </script>

</head>

<body onload = "javascript:addPlacemarkOnMap('Москва')">

<div id="map" style="width:600px; height:300px"></div>

</body>

</html>

 

 

Очень прошу помочь!

28 комментариев

По событию загрузки документа (body onload) АПИ еще не будет загружено

Используйте метод ymaps.ready

saniarium.saniarium
28 января 2016, 04:04

Напишите, пожалуйста, код

 

 

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

http://www.w3.org/1999/xhtml">

 

 

Примеры. Геопоиск.

 

 

 

 

 

 

 

 

 

 

 

 

 

Прямое геокодирование

 

 

 

 

 

 

saniarium.saniarium
28 января 2016, 04:04

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

saniarium.saniarium
28 января 2016, 04:04

Спасибо, разобралась.

сделайте отдельной

 

function geocode(request, callback) {

     ymaps.geocode(request)

         .then(function (res) {

              callback(null, res);

          }, function (err) {

              callback(err);

      });

}

тогда можно вызывать так:

var myMap;

function init() {

    geocode('Нижний Новгород', function (err, result) {

           if(myMap) {                           myMap.setCenter(result.geometry.getCoordinates());          }          else {                  myMap = new ymaps.Map("map", {
                      center: result.geometry.getCoordinates(),
                      zoom: 11
                  });            }    });}

 

 

saniarium.saniarium
28 января 2016, 04:04

Подскажите еще; почему в function(err) {alert("Error")}

никогда не появляется сообщение "Error"? Для примера вводила "09090909"

потому что ошибки не происходит

saniarium.saniarium
28 января 2016, 04:04

Что считается ошибкой?

С помощью какой конструкции можно обработать неудачный результат геокодирования (если  неудачей считать - отсутствие метки на карте)?

Ошибкой считаются плохие входные данные или ошибка сервиса.

Отсутствие найденных объектов - не ошибка

saniarium.saniarium
28 января 2016, 04:04

А можно как-то обработать отсутствие "найденных" объектов в 2.х?

можно использовать метод getLength у возвращаемой коллекции чтобы проверить что она не пуста

saniarium.saniarium
28 января 2016, 04:04

Я уже пробовала через getlength(). В моем коде alert(myCollection.getLegth()) вызывается раньше, чем отрисовывается на карте отметка. Поясните ваш метод. Можно как-то иначе отработать результат геокодирования в обход конструкции .then()?

 

function findPlacemarkOnMap(adress){

 

var myCollection = new ymaps.GeoObjectCollection();

 

ymaps.geocode(adress, {results: 1}).then(

function (res){

myCollection.add(res.geoObjects);

myMap.geoObjects.add(myCollection);

},

// Ошибка сервера или "плохие" входные данные

// Не срабатывает в случае неотображения объектов на карте

function (err){

alert(err.message);

});

 

alert(myCollection.getLength());

 

}

 

без then нельзя - запрос асинхронный

перенесите вызов getLength в then

saniarium.saniarium
28 января 2016, 04:04

Я переношу. Но он действует только внутри этого .then(), за пределами - нет. Я создаю функцию findPlacemarkOnMap не только для того, чтобы разместить метку на карте, но чтобы в ответ в 1С получить и результат геокодирования. Потому что я буду добавлять не найденные адреса в отдельную таблицу.

Может это вообще не через geocode делать надо или лучше изучать 1.х?

function findPlacemarkOnMap(adress, returnResult){

var myCollection = new ymaps.GeoObjectCollection();

 

ymaps.geocode(adress, {results: 1}).then(

function (res){

myCollection.add(res.geoObjects);

myMap.geoObjects.add(myCollection);

if (myCollection.getLength() == 0) {returnResult = false} else {returnResult = true};

},

// Ошибка сервера или "плохие" входные данные

// Не срабатывает в случае неотображения объектов на карте

function (err){

alert(err.message);

});

 

return returnResult;

}

там и надо в then

1 АПИ или 2-е разницы нет

http-запрос всегда возвращает результат асинхронно 

 

saniarium.saniarium
28 января 2016, 04:04

Есть примеры с похожим функционал?

saniarium.saniarium
28 января 2016, 04:04

Мне это нужно для того, чтобы понимать - прошло геокодирование или нет, и передавать результат в программу

Это рабочий код для 1С на API 1.x

 

Функция hex(Знач Значение)
 Значение=Число(Значение);
 Если Значение  Результат="0";
 Иначе
  Значение=Цел(Значение);
  Результат="";
  Пока Значение>0 Цикл
   Результат=Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Значение%16 + 1,1)+Результат;
   Значение=Цел(Значение/16) ;
  КонецЦикла;
 КонецЕсли;
 Если СтрДлина(Результат) < 2 Тогда
 
  Результат = "0" + Результат;
 
 КонецЕсли;
 Возврат "%" + Результат;
КонецФункции
Функция EncodeURL(URL)
 
 // отсюда: http://www.w3.org/International/URLUTF8Encoder.java
 
 Рез = "";
 
 Для Сч = 1 По СтрДлина(URL) Цикл
  
  ch = Сред(URL,Сч,1);
  vch = КодСимвола(ch);
  
  Если ("A"    Рез = Рез + ch;
  ИначеЕсли ("a"    Рез = Рез + ch;
  ИначеЕсли ("0"    Рез = Рез + ch;
  ИначеЕсли (ch = " ") ИЛИ ( ch = "+") Тогда   // space
   Рез = Рез + "+";
  ИначеЕсли (ch = "-" ) ИЛИ ( ch = "_") Тогда  // unreserved
   // ch == '.' || ch == '!'
   // ch == '~' || ch == '*'
   // ch == '\'' || ch == '('
   // ch == ')') Тогда
   Рез = Рез + ch;
  ИначеЕсли (vch    Рез = Рез + hex(vch);
  ИначеЕсли (vch    Рез = Рез + hex(192 + Цел(vch / 64));
   Рез = Рез + hex(128 + (vch % 64));
  Иначе     // 0x7FF < ch    Рез = Рез + hex(224 + Цел(vch / 4096));
   Рез = Рез + hex(128 + (Цел(vch / 64) % 64));
   Рез = Рез + hex(128 + (vch % 64));
  КонецЕсли;
     
 КонецЦикла;
 
 Возврат Рез;
КонецФункции // ()
Функция YandexGeoCodeGetFile(Адрес, Ключ, ПроксиСервер, АдресOutput)
 HTTPСервис = Новый HTTPСоединение("geocode-maps.yandex.ru",,,,ПроксиСервер,Ложь);
 
 Попытка
  HTTPСервис.Получить("1.x/?geocode=" + EncodeURL(Адрес) + "&key=" + Ключ, АдресOutput);
 Исключение
  Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
  Возврат Ложь;
 КонецПопытки;
 Возврат Истина;
 
КонецФункции // YandexGeoCodeGetFile()
Функция YandexGeoCode(Адрес, Ключ, ПроксиСервер, Рез) Экспорт
 
 Рез = Новый Структура("lat, lng, Представление", 0, 0, "");
 ИмяТемпФайла = ПолучитьИмяВременногоФайла("xml");
 АдресOutput = _КаталогВременныхФайлов + ИмяТемпФайла;
 //АдресOutput = _КаталогВременныхФайлов + "geores.xml";
 
 Если Не YandexGeoCodeGetFile(Адрес, Ключ, ПроксиСервер, АдресOutput) Тогда
  Попытка
   УдалитьФайлы(АдресOutput);
  Исключение
   //Сообщить(ОписаниеОшибки());
  КонецПопытки;
  Возврат Ложь; 
  
 КонецЕсли;
 
 ЧтениеXML = Новый ЧтениеXML;
 ЧтениеXML.ОткрытьФайл(АдресOutput);
 ПостроительDOM = Новый ПостроительDOM;
 ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
 СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
 СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
 
 Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
  Попытка
   УдалитьФайлы(АдресOutput);
  Исключение
   //Сообщить(ОписаниеОшибки());
  КонецПопытки;
  
  Возврат Ложь; 
  
 КонецЕсли;
 
 Рез.Представление = СписокText[0].ТекстовоеСодержимое;
 Рез.lng = СписокPos[0].ТекстовоеСодержимое;
 ПОз1 = Найти(Рез.lng," ");
 Рез.lat = Сред(Рез.lng, Поз1 + 1);
 Рез.lng = Лев(Рез.lng, Поз1 -1);
 Попытка
  УдалитьФайлы(АдресOutput);
 Исключение
  //Сообщить(ОписаниеОшибки());
 КонецПопытки;
    Возврат Истина;
 
КонецФункции // GeoCode()
Функция ГеокодироватьЭкспорт(Адрес) Экспорт
 Перем Рез;
 Результат = YandexGeoCode(Адрес, KeyAPI, ПроксиСервер, Рез);
 Если не Результат Тогда
  Рез = Неопределено;
 КонецЕсли;
 Возврат Рез;
КонецФункции // ГеокодироватьЭкспорт()

 

saniarium.saniarium
28 января 2016, 04:04

Большое спасибо. Но на 1.x у меня все работает)))

Яндекс.Карты нельзя использовать в десктопных приложениях и закрытых системах. Только сайты.

Ознакомьтесь, пожалуйста, с пользовательским соглашением. http://legal.yandex.ru/maps_api/.
saniarium.saniarium
28 января 2016, 04:04

Спасибо, ознакомилась.

Мне не принципиальна среда. Подскажите: если я создам html-страницу (не опубликованную в интернете), которая по функционалу польностью будет заменять десктоп-приложение, то это не нарушение соглашения?

К сожалению, нарушите, так как к карте должен быть открытый, неограниченный доступ. См. п. 2.3.2. «Сервис может использоваться Пользователем только в рамках сайтов, доступных для бесплатного открытого использования неограниченным кругом лиц. Сервис не может использоваться для проектов, требующих оплаты, или иным образом ограничивающих доступ к ним третьих лиц. Необходимость зарегистрироваться не считается ограничением доступа в рамках настоящего пункта».
saniarium.saniarium
28 января 2016, 04:04

Если я правильно поняла, то:

1. Я могу зарегистрировать на бесплатном домене сайт и повесить код туда.

2. Если это приложение, то можно выставить его на публичном ресурсе для свободного скачивания?

1. Можете. Но доступ должен быть открытым для всех пользователей.
2. Нет. Приложение совсем нельзя делать :-(
saniarium.saniarium
28 января 2016, 04:04

И еще вопрос) чтобы до конца разобраться в вопросе.

1С может работать в режиме веб-клиента при публикации в www-пространстве. Доступ может быть свободным, регистрация и установка ПО не требуется (т.к. веб-клиент работает на js). В этом случае приложение будет являться веб-сервисом и удовлетворять условиям соглашения?

saniarium.saniarium
28 января 2016, 04:04

Как всегда - решение простое. Использование callback-функций. Я всегда по итогу размещаю рабочий код. Поэтому вот:

 

http://www.w3.org/1999/xhtml">

Примеры. Размещение карты на странице.

 

 

         

Подскажите, пожалуйста, вот по вашему коду вызывается окошко с данными из переменной result, а как все-таки эти данные в 1С получить, пытаюсь где-нибудь return воткнуть(функцию findPlacemarkOnMap пытаюсь из 1С запустить), ничего не возвращает..:(