2011-12-13 10 views
0

私は、Googleマップで最もマーカを置いた状態で、センターとズームを州レベルに設定する必要があります。私が作業しているすべてのデータは、ポイント(緯度/経度)のコレクションです。Google Maps API V3:ほとんどのマーカーで状態をズームする

ポイントごとにジオロケーション呼び出し(http://code.google.com/apis/maps/documentation/geocoding/index.html#GeocodingRequests - 参照:ジオコーディングを参照)を実行し、表示する必要がある状態を数えますが、マップごとに数百から数千のポイントがあるため、実用的ではない。

私はこれを達成するために他に何かできますか?類似している可能性のあるものはありますか(高濃度のマーカーの元/中心)?

+0

私はあなたが状態の異なるサイズのため数学的に何かにトリップするつもりであるように感じる...あなたのマーカーが完璧なグリッドに配置されたと想像して...あなたは、各マーカーがどの状態にあるのかを知ることができます。あなたのソースがその部分を供給できるので、各点を逆ジオコードにする必要はありませんか? –

+0

ソースはそのデータを提供できません。マーカーの濃度が最も高い一般的な領域にズームする方法(状態の指定を無視して)を見つけることができれば、私は後退しても構いません。私はこれが非常によく考え出された要求ではないことを認識していますが、私はそれらに何かを与えなければなりません。 – smp7d

+0

疑似逆転はどうですか?最大と最小の緯度(経度と同じ)をとり、Xで割って、各マーカーを配置するごとに、各スライスのカウンタを増やしてください...その後、Googleに電話しなくても一般的なアイデアが得られます毎回 –

答えて

1

ここにアイデアがあります。このSO Questionを参照してください。最初の回答には、すべての州境のポリゴン座標を持つXMLファイルへのリンクがあります。あまりにも多くの頂点がないようにポリゴンを単純化することもできます。

マーカーがマップに追加されたとき、あなたはそれがthisのようなアルゴリズムを使用して、50ポイントのアレイのうちの1つに存在するかどうかを確認することができます

UPDATE:私は掲載元の関数はJavaScriptではなかったです。ここではJavascriptを1とfiddle of it workingです:

/* 
* state == array of Google LatLng objects. 
* lat == latitude to test 
* lng == longitude to test 
*/ 
function pointInPolygon(state, lat, lng) { 
    var polyCount = state.length; 
    var oddNodes = false; 
    var j = 0; 
    for (var i = 0; i < polyCount; i++) { 
     j++; 
     if (j == polyCount) { 
      j = 0; 
     } 
     latitudeBoundry = state[i].lat(); 
     longitudeBoundry = state[i].lng(); 
     latitudeBoundry2 = state[j].lat(); 
     longitudeBoundry2 = state[j].lng(); 
     if ((latitudeBoundry > lat && latitudeBoundry <= lat 
      || latitudeBoundry2 > lat && latitudeBoundry <= lat)) { 
      if (longitudeBoundry + (lat - latitudeBoundry) 
       /(latitudeBoundry2 - latitudeBoundry) 
       * (longitudeBoundry2 - longitudeBoundry) > lng) { 
       oddNodes = !oddNodes 
      } 
     } 
    } 
    return oddNodes; 
} 

それはカウンタをインクリメント存在する場合。

最もマーカの多い状態が見つかったら、境界オブジェクトを作成してズームを設定できます。

//the polyArray is the array of points for the target state. 
var bounds = new google.maps.LatLngBounds(); 
for (var i = 0; i < polyArray.length; i++) 
{ 
    bounds.extend(polyArray[ i ]); 
} 

//set the map viewport 
map.fitBounds(bounds) 

これは、パフォーマンスが賢明になる方法についてはわかりませんが、逆ジオコーディングよりもはるかに速いはずです。

+0

そのpointInPolygon関数が機能するなら、これは実際には答えかもしれません。しかし、私はこれが実用的な方法がないと推測することを念頭に置いています。私は、このアルゴリズムを何千ものマーカーごとに50回実行する予定です。私はそれにショットを与えるかもしれない、ありがとう。 – smp7d

+1

私はそれが実用的でないかもしれないことに同意するが、それは私が頭の上から考えることができるすべてである。 http://gis.stackexchange.com/に行き、GISのプロフェッショナルが何かアイデアを持っているかどうかを確認することができます。 –

1

ここに、前述のグリッド方法を実装するサンプルページがあります。これは、Bryansの概念と似ていますが、それだけでグリッドにどのセクタを決定するための簡単な部門ですので、それは大規模なデータセットに少し速いかもしれ(ただし、状態の特異性を失いません):

<!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> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Auto Center</title> 
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> 
<style> 
#wrap {width:960px;margin-right:auto;margin-left:auto;position:relative;} 
#map_canvas {width:100%;height:700px;} 
table,td {border-collapse:collapse;border:thin #000 solid;} 
</style> 
</head> 
<body> 
<div id="wrap"> 
<div id="map_canvas"></div> 
<div id="tabular"></div> 
<script type="text/javascript"> 
function randomFromTo(from, to){ 
    return Math.floor(Math.random() * (to - from + 1) + from); 
} 
    var map; 
    var placesToFilter=Array(); 
    var myOptions = {zoom: 6,mapTypeControl: false,mapTypeId: google.maps.MapTypeId.ROADMAP}; 
    //---Creating random data 
    for(i=0;i<500;i++){ 
     var a=new Object(); 
     a.lat=randomFromTo(2600,4900)/100; 
     a.lng=-randomFromTo(6600,12500)/100; 
     placesToFilter.push(a); 
    } 
    //---Get max and min latitude 
    var maxLat=placesToFilter[0].lat*1; 
    var minLat=placesToFilter[0].lat*1; 
    for (i=1;i<placesToFilter.length;i++) { 
     if (placesToFilter[i].lat*1>maxLat) {maxLat=placesToFilter[i].lat*1;} 
     if (placesToFilter[i].lat*1<minLat) {minLat=placesToFilter[i].lat*1;} 
    } 
    //---Get max and min longitude 
    var maxLng=placesToFilter[0].lng*1; 
    var minLng=placesToFilter[0].lng*1; 
    for (i=1;i<placesToFilter.length;i++) { 
     if (placesToFilter[i].lng*1>maxLng) {maxLng=placesToFilter[i].lng*1;} 
     if (placesToFilter[i].lng*1<minLng) {minLng=placesToFilter[i].lng*1;} 
    } 
    var s=8;//--------------------How many rows/columns the area gets gridded into 
    var latDelta=maxLat-minLat; 
    var lngDelta=maxLng-minLng; 
    var latStep=latDelta/s; 
    var lngStep=lngDelta/s; 
    var latBands=Array(); 
    for(i=1;i<=s;i++){latBands.push(i*latStep);} 
    var lngBands=Array(); 
    for(i=1;i<=s;i++){lngBands.push(i*lngStep);} 
    //---Keeping score in these arrays 
    var gridCount=new Array(); 
    for(var x=0;x<s;x++){ 
     for(var y=0;y<s;y++){ 
      var cell=[x,y]; 
      gridCount.push(cell); 
     } 
    } 
    for(var lt=0;lt<s;lt++){ 
     for(var lg=0;lg<s;lg++){ 
      gridCount[lt][lg]=0; 
     } 
    } 

    map = new google.maps.Map(document.getElementById('map_canvas'),myOptions); 

    for(p=0;p<placesToFilter.length;p++){ 
     //---Keeping track of which grid sector 
     var whichLat=Math.floor((placesToFilter[p].lat-minLat)/latStep); 
     var whichLng=Math.floor((placesToFilter[p].lng-minLng)/lngStep); 
     gridCount[whichLat][whichLng]++; 
     //---And placing the marker 
     var point=new google.maps.LatLng(placesToFilter[p].lat,placesToFilter[p].lng); 
     var marker = new google.maps.Marker({position: point,map: map}); 
    } 
    //---Figuring out which cell 'won' 
    var checking=gridCount[0][0]; 
    var rightLat; 
    var rightLng; 
    for(lt=0;lt<s;lt++){ 
     for(lg=0;lg<s;lg++){ 
      if(gridCount[lt][lg]>checking){ 
       checking=gridCount[lt][lg]; 
       rightLat=lt; 
       rightLng=lg; 
      } 
     } 
    } 
    //convert grid sector to lat/lng (center of sector) 
    var winningLat=maxLat-(rightLat*latStep)-(latStep/2); 
    var winningLng=minLng+(rightLng*lngStep)+(lngStep/2); 
    var newCenter=new google.maps.LatLng(winningLat,winningLng); 
    map.setCenter(newCenter); 
    showTable=true; //--------------this will display the table of data so you can see how many markers are in each sector 
    if(showTable){ 
     var table='<table>'; 
     for(row=0;row<s;row++){ 
      table+='<tr>'; 
      for(td=0;td<s;td++){ 
       table+='<td>'+gridCount[row][td]+'</td>'; 
      } 
      table+='</tr>'; 
     } 
     table+='</table>'; 
     document.getElementById('tabular').innerHTML=table; 
    } 
</script> 
</div> 
</body> 
</html> 
関連する問題