OpenLayersで説明されている問題と同様の問題: ズームインまたはズームアウト後に破壊されたフィーチャが再表示される
ベクターレイヤーで destroyFeatures() または removeAllFeatures() (または両方、どちらかの順序で) を呼び出します。フィーチャがビューから消えます。しかし、ズームインまたはズームアウトすると、再び表示されます。私の場合、これはクラスタリング戦略が使用されている場合にのみ発生します。クラスター フィーチャは破壊されているように見えますが、そのクラスターによって表される基になるフィーチャは破壊されていないため、拡大または縮小すると、それらの基になるフィーチャからクラスタリングが再計算され、再描画されます。
Google で検索すると、destroyFeatures() の問題に関して、数年前に OpenLayers の開発者の間で交わされた多くの会話が明らかになりました。今でも、問題が完全に解決されていないように見えるのは驚くべきことです。
(destroy() を使用して) レイヤー全体を破棄し、必要に応じてレイヤーを再作成することで、この問題を回避できます。私の場合はそれで問題ありませんが、そのようなばかげたアプローチが望ましくない場合も想像できます。
コード サンプルのリクエストに応えて、動作しているバージョンのコードの短縮バージョンを次に示します (つまり、destroy() を使用)。動作しないバージョンでは、代わりに destroyFeatures() を呼び出しました (レイヤーを null に設定しませんでした)。前述のように、これにより最初はフィーチャが消去されますが、後で this.map.zoomIn() を使用してズームインまたはズームアウトすると、フィーチャが再び表示されます。
注 1: 関数は、JavaScript ブリッジを介して Objective-C から呼び出されます。注 2: JavaScript は CoffeeScript を使用して生成されました。
(function() {
var addSightingsLayer, displayFeaturesForSightingsWithGeoJSONData, geoJSONFormat, load, map, projectionSphericalMercator, projectionWGS84, removeSightingsLayer, sightingsLayer;
addSightingsLayer = function() {
var context, layerStyle, layerStyleSelected, style, styleMap, styleSelected, yerClusteringStrategy;
if (!(this.sightingsLayer === null)) return;
yerClusteringStrategy = new OpenLayers.Strategy.Cluster({
distance: 10,
threshold: 2
});
this.sightingsLayer = new OpenLayers.Layer.Vector('Sightings', {
strategies: [yerClusteringStrategy]
});
this.map.addLayer(this.sightingsLayer);
style = {
// Here I define a style
};
context = {
// Here I define a context, with several functions depending on whether there is a cluster or not, eg:
dependentLabel: function(feature) {
if (feature.cluster) {
return feature.attributes.count;
} else {
return feature.attributes.name;
}
}, ....
};
layerStyle = new OpenLayers.Style(style, {
context: context
});
styleSelected = {
//...
};
layerStyleSelected = new OpenLayers.Style(styleSelected, {
context: context
});
styleMap = new OpenLayers.StyleMap({
'default': layerStyle,
'select': layerStyleSelected
});
this.sightingsLayer.styleMap = styleMap;
};
removeSightingsLayer = function() {
if (this.sightingsLayer === null) return;
this.sightingsLayer.destroy();
return this.sightingsLayer = null;
};
displayFeaturesForSightingsWithGeoJSONData = function(geoJSONData) {
if (this.sightingsLayer === null) JFOLMap.addSightingsLayer();
return this.sightingsLayer.addFeatures(this.geoJSONFormat.read(geoJSONData));
};
load = function() {
var lat, lon, osmLayer, zoom;
lat = ...;
lon = ...;
zoom = ...;
this.map = new OpenLayers.Map('mapDiv', {
controls: ...,
eventListeners: ...
});
osmLayer = new OpenLayers.Layer.OSM();
this.map.addLayer(osmLayer);
return this.map.setCenter(new OpenLayers.LonLat(lon, lat).transformWGS84ToSphericalMercator(), zoom);
};
OpenLayers.LonLat.prototype.transformWGS84ToSphericalMercator = function() {
return this.transform(JFOLMap.projectionWGS84, JFOLMap.projectionSphericalMercator);
};
OpenLayers.LonLat.prototype.transformSphericalMercatorToWGS84 = function() {
return this.transform(JFOLMap.projectionSphericalMercator, JFOLMap.projectionWGS84);
};
map = null;
sightingsLayer = null;
sightingsPopoverControl = null;
projectionWGS84 = new OpenLayers.Projection('EPSG:4326');
projectionSphericalMercator = new OpenLayers.Projection('EPSG:900913');
geoJSONFormat = new OpenLayers.Format.GeoJSON({
'externalProjection': projectionWGS84,
'internalProjection': projectionSphericalMercator
});
this.JFOLMap = {
map: map,
sightingsLayer: sightingsLayer,
projectionSphericalMercator: projectionSphericalMercator,
projectionWGS84: projectionWGS84,
geoJSONFormat: geoJSONFormat,
load: load,
addSightingsLayer: addSightingsLayer,
removeSightingsLayer: removeSightingsLayer,
displayFeaturesForSightingsWithGeoJSONData: displayFeaturesForSightingsWithGeoJSONData,
};
}).call(this);