2016-08-18 363 views
1

我最近的任務是爲我的Wurm在線遊戲聯盟創建地圖。我在遊戲內地圖的靜態圖像上製作了一個基於SVG的天才疊加圖。基本上,它從電子表格中獲取數據,並將村莊呈現爲地圖上的彩色圓圈。OpenLayers3自定義地圖縮放標記縮放

但是,我們所有的成員都在地圖上,所以想要了解如何創建一個可縮放的基於Web的我們的土地地圖。遊戲管理員每年或每年都會給我們一張地圖轉儲圖,所以我們可以創建自定義地圖應用程序,但我們感覺。我下載了Xanadu關心的島嶼/服務器最近的地圖轉儲。

Xanadu轉儲是一個62MB PNG,分辨率爲8192 x 8192像素。我發現了一個瓷磚製作程序(MapTiler版本7),然後我開始製作瓷磚。瓷磚完成渲染後,程序本身會以編程方式創建帶有嵌入式JavaScript的HTML文件。它給了我一個OpenLayers3的開端。

我能夠重新計算村的座標,並湊齊一個村莊圈子的縮放平鋪地圖。不用說,當我獲得自定義的OpenLayers3地圖時,我非常高興。 (工作示例:http://jackswurmtools.com/Content/Static/map.html

我設置它的方式,每個地圖「裝飾」或彩色圓圈都是它自己的Vector。

我的同伴們對我的可縮放地圖的主要抱怨是顏色村莊的圓圈太大,放大時太小。 我嘗試了各種各樣的東西,但我有還沒有找到正確的例子。我習慣於根據事件來查找和轉換SVG元素,但在DOM中OP3畫布渲染對我來說並不明顯。

我的一些問題是:

  • 我如何檢測時,我的地圖已被放大?有一些我錯過的回調?
  • 當檢測到縮放時,我如何迭代所有矢量並更新圓的半徑。

// jacks fully zoomable xanadu map 
 
var data = 
 
     [{ 
 
     X: "6744", 
 
     Y: "-2355.75", 
 
     Name: "Amish Creek", 
 
     Villagers: ["Aniceset", "Fulano"], 
 
     BackColor: "Aquamarine", 
 
     LandMarkType: "Member" 
 
     }, { 
 
     X: "6808.75", 
 
     Y: "-2265.125", 
 
     Name: "Amish Estates", 
 
     Villagers: ["Aniceset", "Villagers"], 
 
     BackColor: "Purple", 
 
     LandMarkType: "Member" 
 
     }]; 
 
    
 
    
 
console.log(data); 
 

 
var mapExtent = [0.00000000, -8192.00000000, 8192.00000000, 0.00000000]; 
 
var mapMinZoom = 0; 
 
var mapMaxZoom = 5; 
 
var mapMaxResolution = 1.00000000; 
 
var tileExtent = [0.00000000, -8192.00000000, 8192.00000000, 0.00000000]; 
 

 
var mapResolutions = []; 
 
for (var z = 0; z <= mapMaxZoom; z++) { 
 
    mapResolutions.push(Math.pow(2, mapMaxZoom - z) * mapMaxResolution); 
 
} 
 

 
var mapTileGrid = new ol.tilegrid.TileGrid({ 
 
    extent: tileExtent, 
 
    minZoom: mapMinZoom, 
 
    resolutions: mapResolutions 
 
}); 
 

 
var features = []; 
 

 
var map = new ol.Map({ 
 
    target: 'map', 
 
    layers: [ 
 
    new ol.layer.Tile({ 
 
     source: new ol.source.XYZ({ 
 
     projection: 'PNGMAP', 
 
     tileGrid: mapTileGrid, 
 
     url: "http://jackswurmtools.com/Content/Static/{z}/{x}/{y}.png" 
 
     }) 
 
    }), 
 
    ], 
 
    view: new ol.View({ 
 
    zoom: 4, 
 
    center: [6602.375, -2250.3125], 
 
    projection: ol.proj.get('PNGMap'), 
 
    maxResolution: mapTileGrid.getResolution(mapMinZoom) 
 
    }), 
 
}); 
 
map.getView(); 
 

 
map.on('singleclick', function(evt) { 
 
    var coord = evt.coordinate; 
 
    console.log(coord); 
 

 
    $("#coord-overlay").html("[" + coord[0] + ", " + coord[1] + "]"); 
 
}); 
 

 
// zoom stuff? 
 

 

 
// add layers via JSON iteration 
 
renderSVG(data); 
 

 
drawLines(); 
 

 
function renderSVG(data) { 
 
    var vectorSource = new ol.layer.Vector({}); 
 

 
    console.log(map.getView().getZoom()); 
 

 
    jQuery.each(data, function() { 
 

 
    var fill = new ol.style.Fill({ 
 
     color: this.BackColor 
 
    }); 
 

 
    var stroke = new ol.style.Stroke({ 
 
     color: [180, 0, 0, 1], 
 
     width: 1 
 
    }); 
 

 
    var style = new ol.style.Style({ 
 
     image: new ol.style.Circle({ 
 
     fill: fill, 
 
     stroke: stroke, 
 
     radius: map.getView().getZoom() * 5, 
 
     opacity: 0.7 
 
     }), 
 
     fill: fill, 
 
     stroke: stroke, 
 
     text: new ol.style.Text({ 
 
     font: '12px helvetica,sans-serif', 
 
     text: this.Name, 
 
     fill: new ol.style.Fill({ 
 
      color: '#000' 
 
     }), 
 
     stroke: new ol.style.Stroke({ 
 
      color: '#fff', 
 
      width: 2 
 
     }) 
 
     }) 
 
    }); 
 

 
    var point_feature = new ol.Feature({}); 
 

 
    var point_geom = new ol.geom.Point([this.X, this.Y]); 
 
    point_feature.setGeometry(point_geom); 
 

 
    var vector_layer = new ol.layer.Vector({ 
 
     source: new ol.source.Vector({ 
 
     features: [point_feature], 
 

 
     }) 
 
    }); 
 
    vector_layer.setStyle(style); 
 
    map.addLayer(vector_layer); 
 
    }); 
 
} 
 

 
function drawLines() { 
 
    var stroke = new ol.style.Stroke({ 
 
    color: [255, 0, 0, 1], 
 
    width: 6 
 
    }); 
 

 
    var style = new ol.style.Style({ 
 
    fill: null, 
 
    stroke: stroke, 
 
    text: new ol.style.Text({ 
 
     font: '12px helvetica,sans-serif', 
 
     text: "Sandokhan/Wargasm Canal", 
 
     fill: new ol.style.Fill({ 
 
     color: '#000' 
 
     }), 
 
     stroke: new ol.style.Stroke({ 
 
     color: '#fff', 
 
     width: 2 
 
     }) 
 
    }) 
 
    }); 
 

 
    var line_feature = new ol.Feature({}); 
 

 
    var coords = [ 
 
    [6607.5, -1921], 
 
    [6894, -1921] 
 
    ]; 
 

 
    var layerLines = new ol.layer.Vector({ 
 
    source: new ol.source.Vector({ 
 
     features: [new ol.Feature({ 
 
     geometry: new ol.geom.LineString(coords, 'XY'), 
 
     name: 'Line', 
 
     })] 
 
    }) 
 
    }); 
 

 
    layerLines.setStyle(style); 
 

 
    map.addLayer(layerLines); 
 

 

 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.8.2/ol.min.css" type="text/css"> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.8.2/ol.min.js" type="text/javascript"></script> 
 
<div id="map"></div> 
 
<div id="coord-overlay">[6612, -2252]</div> 
 
<input id="slider" type="range" min="0" max="1" step="0.1" value="1" oninput="layer.setOpacity(this.value)">

+0

我認爲我的一個斷開連接是我將我所有的圓圈添加爲我的Village數據迭代器中的單個矢量。我的第一筆業務是將圓圈作爲多個特徵添加到單個矢量中。 – InvoiceGuy

+0

所以,我一直在用我的代碼搞得一團糟......我仍然無法爲Village小區取得多個圖層。現在我需要弄清楚如何以迭代的方式定位向量。 – InvoiceGuy

+0

嘿傢伙..我已經非常努力地利用OL3和矢量圖層處理來努力了。相反,我發現整合OL3和D3是我想去的地方。 以下示例: [鏈接](http://firefly.ibk.se/~racer/ol3_d3_trans.html),我可以在我的Tile圖層上疊加一個SVG圖層,然後重新計算我的SVG與以前的地圖的協調post render event:map.on('postrender',function(event){// stuff}); – InvoiceGuy

回答

0

您正在尋找一個解決聽衆的API docs是一個很好的地方:

map.getView().on('change:resolution', function(){ 
    var zoom = map.getView().getZoom(); 

    // your conditions 
    if (zoom < 10) { 
    // your ol.layer.Vector assuming `vector_layer` global variable 
    vector_layer.setStyle(style_with_another_radius); 
    } 
}); 
1

你可以聽moveend事件變焦,但它在移動地圖時也會被觸發:

map.on('moveend', function(){ 
    var radius= map.getView().getZoom() * someFactor; // or whatever +,/ ... 
    yourVectorVillage.setStyle(new ol.style.Circle({ radius : radius})); 
    // or a style of your own where you can modify the radius 
});