2013-12-12 5 views
0

У меня действительно есть большая проблема, которую я пока не могу решить. Вот моя проблема. На самом деле у меня есть карта, на которой я показываю маркеры (WMSGetFeatureInfo) в зависимости от некоторых категорий, которые я хочу показать или скрыть.OpenLayers: всплывающее окно с несколькими слоями

Но вот что я на самом деле получаю эти маркеры как файл * .map, который на самом деле является файлом PNG, содержащим все маркеры.

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

Вот некоторый код:

var layer = new OpenLayers.Layer.WMS(
     category.label, 
     "/mapserv?Map=" + category.url, 
     { 
      layers : category.layer, 
      format : 'image/png', 
      version : '1.3.0', 
      srs  : 'ESPG:3163' 
     }, 
     { 
      isBaseLayer : false, 
      singleTile : true, 
      visibility : visibility, 
     } 
    ); 

    var info = new OpenLayers.Control.WMSGetFeatureInfo({ 
     title   : 'get details by clicking', 
     layers   : [ layer ], 
     infoFormat  : "text/plain", 
     queryVisible : true, 
     eventListeners : { 
      getfeatureinfo : function(event){ 
       document.body.style.cursor = 'auto'; 

       var getId = function(text) { 
        result = context.settings.pattern.exec(text); 
        if(result == null) return; 
        return result[1]; 
       } 

       var id = getId(event.text); 

       request = jQuery.ajax({ 
        url  : "/cartoweb/FicheTheme", 
        type : "get", 
        data : "idGeoEad="+id, 
        success : function(response, textStatus, jqXHR){ 
         if (response == null || response['data'] == null) { 
          return; 
         } 
         context.generateAndShowPopup(event.xy, response['data']['metaData']); 
        } 
       }); 
      }, 
      beforegetfeatureinfo : function(event){ 
       document.body.style.cursor = 'wait'; 
      }, 
      nogetfeatureinfo : function(event){ 
       document.body.style.cursor = 'auto'; 
      } 
     } 
    }); 

    this.map.addControl(info); 
    info.activate(); 


generateAndShowPopup : function(latlong, text) { 
    var lonlatfrompx = this.map.getLonLatFromViewPortPx(latlong); 
    var anchor  = { 
     'size'  : new OpenLayers.Size(0,0), 
     'offset' : new OpenLayers.Pixel(-36, 6), 
     'keepInMap' : true 
    }; 

    // Hide by default popup actually open 
    if(this.popup !== undefined) { 
     this.popup.hide(); 
    } 

    // Create a new popup 
    this.popup = new OpenLayers.Popup.Anchored(
     "chicken", 
     lonlatfrompx, 
     new OpenLayers.Size(2000, 2000), 
     '<div class="popupTail"></div><div class="popupContent">' + text + '</div>', 
     anchor, 
     false, 
     function(){} 
    ); 

    // Popup settings 
    this.popup.setBackgroundColor('transparent'); 
    this.popup.panMapIfOutOfView   = true; 
    this.popup.calculateRelativePosition = function() { return 'tr'; } 

    // Add it on the map 
    this.map.addPopup(this.popup); 

    var that = this; 
    setTimeout(function(){ 
     that.popup.updateSize(); 
    }, 50); 

    this.map.setCenter(lonlatfrompx); 
} 

Не уверен, что, если я делаю что-то неправильно, но если кто-то уже сталкивался с такой же вопрос, что будет очень полезно знать, где я сделал что-то неправильно.

Большое спасибо

EDIT
Ok поэтому я попытался перепроецировать в LatLong на слое, но он по-прежнему не работает. Тем не менее, я делаю прогресс:

// Layer is the layer associated to each WMSGetFeatureInfo 
// this.layer is the base layer used to display the map 
lonlatfrompx.transform(layer.projection, this.layer.projection); 
this.map.setCenter(lonlatfrompx); 

EDIT 1
Ok, так что я делаю успехи. Думаю, я знаю, откуда эта проблема, но я все еще не вижу/не знаю, как я ее разрешу (пока).

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

Скажем, я показываю на карте 5 разных слоев (ИТ, дизайн, запуск, компьютер и рабочий стол). Затем, когда я нажимаю маркеры (WMSGetFeatureInfo), на самом деле пытаюсь сделать ajax request * [number of layers visible], а затем изменить в какой-то момент (иногда) значение позиции.

Чтобы решить эту проблему, мне нужно будет избежать этого запроса ajax для выполнения более одного раза. Есть идеи?

ответ

0

Когда я впервые прочитал ваше сообщение, я неправильно понял ваш «маркер» OpenLayers.Marker. Думаю, вам лучше по-прежнему называть ваш «маркер» WMSGetFeatureInfo. Пользователям легче следить за ним :)

Лично я думаю, что проблема, которую вы получаете, связана с проекцией вашей карты, ваша проекция слоя «ESPG: 3163», когда вы определяете параметр «lonlatfrompx», вы не перепрограммировали lon/lat (EPSG: 4326) на «ESPG: 3163». Так что это будет неправильно долгота/широты для всплывающего окна ...

Update

Читая ваш «EDIT 1» Я просто заметил, что, как вы написать «переменную информацию = новый OpenLayers.Control. WMSGetFeatureInfo "очень странно, почему вам нужно добавить ajax-вызов внутри вашего WMSGetFeatureInfo? обычный способ сделать это - использовать параметр «url» для запроса wms вместо использования вызова ajax.например:

info = new OpenLayers.Control.WMSGetFeatureInfo({ 
     url: 'http://demo.opengeo.org/geoserver/wms', 
     title: 'Identify features by clicking', 
     queryVisible: true, 
     layers: [layer], 
     eventListeners: { 
      getfeatureinfo: function(event) { 
       // add popup here 
       map.addPopup(new OpenLayers.Popup.FramedCloud(
        "chicken", 
        map.getLonLatFromPixel(event.xy), 
        null, 
        event.text, 
        null, 
        true 
       )); 
      }, 
      beforegetfeatureinfo: function(event) { 
      ...... 
      }, 
      nogetfeatureinfo: function(event) { 
      ...... 
      } 
      ...... 
     } 
    }); 

обновления 2

Первое:

Да, WMSGetFeatureInfo будет отправлять несколько запросов на сервер WMS, если включить несколько источников (слои). вот почему ваш аякс вызвал несколько раз.

У всех слоев в одном и том же положении карты (точка щелчка мыши) есть один и тот же идентификатор (idGeoEad)? если они это сделают, есть быстрый и грязный способ, который обеспечивает только параметр «слоев» на один уровень (вместо массива слоев), тогда вызов ajax будет запускаться только один раз. Или просто не задайте параметры url слоя &, он найдет первый подходящий слой.

Второе:

Даже если это так, на мой взгляд, это не должно повлиять на всплывающую позицию. Потому что «event.xy» и «lonlatfrompx» всегда должны совпадать. Поэтому я думаю, что всплывающее окно, указывающее далеко от соответствующего маркера, все еще вызвано неправильной проекцией. Итак, пожалуйста, дважды проверьте проекцию карты, проекцию отображения карты и проекцию всех слоев. Также, пожалуйста, проверьте правильность проекции ваших слоев на настройку вашего картотек? Все слои используют «EPSG: 3163»? В приведенном выше коде я замечаю, что опечатка «srs:« ESPG: 3163 », это должен быть EPSG: 3163.

Если вы используете fire-bug или инструмент для разработки Google, отлаживайте или console.log, чтобы увидеть, будут ли «event.xy» и «lonlatfrompx» получать правильное положение каждый раз.

+0

Спасибо за ваш андерсер. Это интересно. Однако, поскольку я новичок в Openlayer, что я могу сделать? Я отредактировал мой пост после того, как попробовал другие вещи, но все равно не успел :(Спасибо – lkartono

+0

plz см. Мое обновление – JSC

+0

Привет, спасибо за обновление. Я использую ajax, потому что URL-адрес отличается от сервера WMS '/ cartoweb/FicheTheme? IdGeoEad = '. Фактическая система не основана на сервере для получения данных, поэтому мне нужно запросить конкретный URL-адрес, содержащий идентификатор, чтобы вернуть информацию, связанную с маркером. Странное поведение, которое я заметил, заключается в том, что если есть, например, 3 слоя на карте, 'eventListeners: getfeatureinfo' выполняется 3 раза и иногда возвращает значения mulitple. В этот момент, похоже, ломается. Я пытаюсь использовать' drillDown', но все еще не работает :(Мысли? – lkartono

Смежные вопросы