OpenLayers3自定义地图缩放标记缩放

时间:2016-08-18 02:23:59

标签: javascript openlayers-3

我最近负责为我的Wurm Online游戏联盟创建地图。我在游戏地图的静态图像上制作了一个基于SVG的天才叠加层。基本上,它从电子表格中获取数据,并在地图上将乡村渲染为彩色圆圈。

但是,我们在地图上都有会员,所以我们就可以看看如何创建一个可缩放的基于网络的地图。游戏管理员每年或每周给我们一个地图转储,所以我们可以创建自定义地图应用程序。我下载了最近我关心的岛/服务器的地图转储,Xanadu。

Xanadu转储是一个62MB的PNG,分辨率为8192 x 8192像素。我发现了一个瓷砖制作程序(MapTiler版本7),我开始创建瓷砖。在完成渲染后,程序本身会以编程方式创建带有嵌入式JavaScript的HTML文件。它让我对OpenLayers3有了一个良好的开端。

我能够重新计算Village坐标,并用Village圈子拼凑出可缩放的平铺地图。毋庸置疑,当我获得自定义的OpenLayers3地图时,我感到非常高兴。 (工作示例:http://jackswurmtools.com/Content/Static/map.html

我设置它的方式,每个地图"装饰"或彩色圆圈是它自己的Vector。

我的游戏玩家对我的可缩放地图的主要抱怨是,颜色的村庄圆圈缩小得太大,但放大时太小了。 我尝试了各种各样的事情,但我还没有找到合适的例子。我习惯于根据事件查找和转换SVG元素,但OP3画布渲染在DOM中并不明显。

我的一些问题是:

  • 如何检测地图缩放的时间?我有一些回调吗?
  • 当检测到变焦时,如何迭代所有矢量并更新圆半径。



// 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);


}
&#13;
<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)">
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分: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
});

答案 1 :(得分: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);
  }
});