javascript - OpenLayers3 自定义 map 在缩放时调整标记大小

标签 javascript openlayers-3

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

但是,我们的成员遍布整个 map ,因此我想看看如何创建一个可缩放的基于网络的 map 。游戏管理员每年都会向我们提供一次 map 转储,因此我们可以根据自己的感觉创建自定义 map 应用程序。我下载了我关心的岛屿/服务器“世外桃源”(Xanadu) 的最新 map 转储。

Xanadu 转储是 62MB PNG,分辨率为 8192 x 8192 像素。我找到了一个图 block 制作程序(MapTiler 版本 7),然后我开始创建图 block 。图 block 渲染完成后,程序本身会以编程方式创建嵌入 JavaScript 的 HTML 文件。它让我在使用 OpenLayers3 方面取得了先机。

我能够重新计算村庄坐标,并将可缩放的平铺 map 与村庄圆圈拼凑在一起。不用说,当我收到自定义 OpenLayers3 map 时,我非常高兴。 (工作示例:http://jackswurmtools.com/Content/Static/map.html)

我的设置方式是,每个 map “装饰”或彩色圆圈都是它自己的矢量。

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

我的一些问题是:

  • 如何检测我的 map 何时被缩放?我缺少一些回调吗?
  • 当检测到缩放时,如何迭代所有向量并更新圆半径。

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

最佳答案

您正在寻找一个解析监听器,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);
  }
});

关于javascript - OpenLayers3 自定义 map 在缩放时调整标记大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39009016/

相关文章:

javascript - 解析没有变量赋值的函数表达式

javascript - 开放层 3 : How to change/set the style of vector map

javascript - 如何使用 angular.element ('#id' 获取输入元素的值)

javascript - AngularJS 中的链式 Promis

openlayers-3 - 是否可以向多边形添加图标符号

openlayers-3 - 在 openlayers 3 中更改拖动时的光标

openlayers-3 - openlayers 3 中基于规则的样式

javascript - 在 typescript/angular2 中使用 openlayer3

javascript - 三元运算符期间对象可能未定义

javascript - thinkster 上的 Angularfire