【问题标题】:Coldfusion + Google Map API v3 — info window and set boundsColdfusion + Google Map API v3 — 信息窗口和设置边界
【发布时间】:2010-10-06 19:35:24
【问题描述】:

简单地说,我似乎能够编写代码来为弹出信息窗口创建一个可点击的标记,或者获取返回的标记的边界并重置地图范围和缩放级别。我似乎无法将两者结合起来。 我下面的示例将很好地将地图的范围设置为查询结果。但鉴于我的循环结构如何,我不太清楚如何将 addListener 事件包含到标记中,并且在 var mapOptions 中,我设置了中心:gbounds.getCenter()。这两个问题似乎使我向地图或标记添加事件的能力复杂化。

    <cfquery name="myquery" datasource="xxxx">
       SELECT name, lat, long
       FROM tblMain
    </cfquery>

    <cfset bridgeCoord=arrayNew(1)>

    <cfloop query="myquery">
   <cfset bridge[CurrentRow] = structNew()>
   <cfset bridge[CurrentRow].lat=lat>
       <cfset bridge[CurrentRow].long=longX>
          <cfset bridge[CurrentRow].name=name>
     </cfloop>



     <script>
       $(document).ready(function() {
       var gbounds = new google.maps.LatLngBounds();
        var markers = [];


       <cfloop index="mi" array="#bridge#">
           <cfoutput> 
               //make the point
               var point = new google.maps.LatLng(#mi.lat#,#mi.long#);
               gbounds.extend(point);
               //make the marker
               var marker = new google.maps.Marker({position: point, title:"#mi.name#"});
               markers[markers.length] = marker; 
            </cfoutput>
       </cfloop>

              var mapOptions = {
                    zoom:3,
                    mapTypeControl: true,
                    mapTypeControlOptions: {
                    style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
                       },
                     mapTypeId:google.maps.MapTypeId.ROADMAP,
                     center:gbounds.getCenter()
                        };



        var map = new google.maps.Map(document.getElementById('myMap'), mapOptions);

           map.fitBounds(gbounds);

           for(var i=0; i<markers.length; i++) markers[i].setMap(map);

      });

fyi,我也尝试过组织部分代码,如下所示。 这非常适合将点击事件添加到标记,但我似乎无法使用我的 center:gbounds.getCenter() 或 map.fitBounds() 元素 b/c 首先设置 mapOptions并传递给新的 map 变量,此时尚未定义 gbounds。将 lat/long 硬编码到中心:似乎只是保留在那里。

       function initialize() {

    var gbounds = new google.maps.LatLngBounds();    


  var myOptions = {
    zoom: 4,
    center: new google.maps.LatLng(39.0,-94.1),
    mapTypeControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("myMap"),
                                myOptions);

  google.maps.event.addListener(map, 'click', function() {
        infowindow.close();
        });

  // Add markers to the map
  // Set up three markers with info windows 

    <cfloop index="mi" array="#bridge#">
        <cfoutput>

             //make the point
               var point = new google.maps.LatLng(#mi.lat#,#mi.long#);
            gbounds.extend(point);
            //make the marker
               var marker = createMarker(point, "#mi.name#", "#mi.name#")

        </cfoutput>
    </cfloop>


}
 map.fitBounds(gbounds);;

function createMarker(latlng, tip, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        title: tip,
        map: map,
        });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
        });
}


var infowindow = new google.maps.InfoWindow(
  { 
    size: new google.maps.Size(150,50)
  });

10/12 更新: 让它工作。 Tyler 的代码中确实有一个错字,但很小。我不确定我能多好地使用这段代码并对其进行扩展,因为我对 jQuery 不是很精通,但这是一个开始。我正在努力解决的一件事是在返回零标记时如何处理地图。在我的查询中可能无法返回任何记录。发生的情况是地图绘制但它在海洋中间居中并缩放。我认为它应该默认为我设置的中心(中心:new google.maps.LatLng(39, -94.1) 但它没有。

Replace: 

var $markers = $container.find(".map-marker");

with

var $markers = $container.find(".mapMarker");

【问题讨论】:

  • 嘿,那段代码看起来很眼熟 - 是来自我的博文吗? :) 无论如何 - 所以在你的第二个例子中,你为什么要移动循环?为什么不将它保留在原来的位置?
  • 是的。你帮助我开始了。可能,b/c 我正在从您的示例中将地图移动到返回点的边界,以及另一个示例(设置不同但与其他示例更一致)来创建标记窗口。为此,我必须在循环中调用一个函数(上面的示例没有这样做。)您在地图选项 var 中有 center:gbounds.getCenter(),这必须在声明 var 地图之前发生。当 createMarker 函数需要 map:map 时不知道该怎么做,因此必须首先声明“map”(但是,如何告诉它 center: 是什么?)

标签: google-maps coldfusion multidimensional-array cfquery


【解决方案1】:

编辑

实际上我大约一个月前才处理过这个问题,这里有一些对我有用的修改代码,使它更像你的。

Google Maps API v3 和 jQuery 1.4.2(尽管这应该适用于任何版本的 jQuery,并且将其移植到 strait javascript 或其他库应该是小菜一碟)

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>

<cfquery name="mi" datasource="xxxx">
SELECT name, lat, long, content
FROM tblName
</cfquery>

<ul id="mapMarkers">
<cfoutput query="mi">
    <li class="mapMarker" data-latitude="#mi.lat#" data-longitude="#mi.long#">
        <div class="info-window">
        <h1 class="name">#mi.name#</a></h1>
        <div class="content">#mi.content#</div>
        </div>
    </li>
</cfoutput>
</ul>
<div id="map"></div>

<script type="text/javascript">
$(function() {
    var $container = $("#mapMarkers");

    var $map = $("#map");
    var $markers = $container.find(".map-marker");

    var bounds = new google.maps.LatLngBounds();
    var infowindow = new google.maps.InfoWindow({
        maxWidth: 300
    });

    var gmap = new google.maps.Map($map[0], {
        zoom: 8
        , mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    $markers.each(function(){
        $this = $(this);
        var latitude = $this.attr("data-latitude");
        var longitude = $this.attr("data-longitude");
        var content = $this.find(".info-window").remove().html();
        var latlng = new google.maps.LatLng(latitude, longitude);

        bounds.extend(latlng);

        var marker = new google.maps.Marker({
            position: latlng
            , map: gmap
        });

        google.maps.event.addListener(marker, 'click', function() {
            infowindow.setContent(content);
            infowindow.open(this.map, this);
        });

        google.maps.event.addListener(gmap, 'click', function() {
            infowindow.close();
        });

        $this.click(function(e, el) {
            e.preventDefault();

            infowindow.setContent(content);
            infowindow.open(gmap, marker);
        })
    });

    if($markers.length > 1)
        gmap.fitBounds(bounds);
    else
        gmap.setCenter(bounds.getCenter());

    $container.hide();
});
</script>

结束编辑

首先,您必须将地图和 mapOptions 移动到顶部。然后在您的循环中,只需将 addListener 添加到标记的地图中:

<cfloop index="mi" array="#bridge#">
   <cfoutput> 
       //make the point
       var point = new google.maps.LatLng(#mi.lat#,#mi.long#);
       gbounds.extend(point);
       //make the marker
       var marker = new google.maps.Marker({position: point, title:"#JSStringFormat(mi.name)#", map:map});
       google.maps.event.addListener(marker, 'click', function() {
           infowindow.setContent("#JSStringFormat(mi.content)#");
           infowindow.open(this.map, this);
       });
       markers[markers.length] = marker; 
    </cfoutput>
</cfloop>

注意事项:

我在 name 和 content 变量中添加了 JSStringFormat。

在标记创建中有一个地图选项,您可以将“map:map”添加到其中,这样您就不必在底部运行 for 循环。

此外,由于您现在是在标记之前创建地图,因此您需要将缩放和居中选项移至底部。

if(markers.length > 1)  
    map.fitBounds(gbounds);  
else  
    map.setCenter(gbounds.getCenter());  

也是最后一件事:

代替

markers[markers.length] = marker;

你可以用这个

markers.push(marker); 

【讨论】:

  • 另外为了更方便,您应该将数据输出到表格或ul中,并添加诸如data-latitude="XX.XXXXXXX"和data-longitude="XX.XXXXXX"等属性。然后对标题和内容使用语义标记。然后使用 jQuery 或您选择的 jslibrary 运行准备好的脚本来收集数据并生成地图以代替上述表格或列表。
  • 另外,放弃转换为数组,只使用查询本身循环。
  • 我将代码添加到帖子的顶部,从语义上讲,我的意思是如果用户没有启用 javascript,记录和信息仍然会显示。这也有助于搜索引擎索引。哦,那里可能有一两个错误。不过没有什么疯狂的,也许只是拼错了什么。
  • 嗯,这很棒。直到星期一我才有机会尝试它,但我会让你知道它是怎么回事。缺点是我在所有这些东西上都是自学的,所以我真的不知道 jquery 语法。如果我能弄清楚如何直接在 js 中执行此操作,那就太好了,这样我就可以将它与其他演示/示例混合在一起。
  • 几乎所有带有 $ 符号的东西都是 jQuery。这一切都非常简单,而且是一个很棒的库,可以让 javascript 变得如此简单。
【解决方案2】:

我不确定问题出在哪里,但如果您解开 JavaScript 和 ColdFusion 代码,您可能会发现更容易调试(和扩展)。您可以在 JS 中编写所有地图逻辑,然后使用 CF 创建 JS 将处理的数据(lat/lng/title 数组)。

<script>
// Data For Map Logic
var points = [];
<cfloop query="...">
  <cfoutput>
    points.push({lat: #db_lat#, lng: #db_lng#, etc...});
  </cfoutput>
</cfloop>

// Logic for setting map extent and creating pop-ups
for (var i = 0; i < points.length; i++) {
  // do your magic
}
</script>

使用这种方法,您可以在测试期间通过对 points 数组进行硬编码来完全消除 CF 和数据库。

【讨论】:

  • 但最终我是从 CF 填充数组。我见过很多硬编码数组的例子。我的问题是使用动态查询。我可以试试你的订单,但我不确定我是否遵循...
猜你喜欢
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多