- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 3 公里网格的某个区域的温度图。IE。我有大约几千个带颜色的多边形。
我正尝试在我的 kotlin 应用程序中将它们显示在 Android 版 Google map 上。
问题是我需要在 UI 线程中添加 GeoJson 层,这需要 8-15 秒。 IE。一直以来,应用程序都被卡住了
StackOverflow 上有很多关于这个问题的旧答案,但它们都与我无关:
我试过:
当 UI 被卡住时,我仍然有或多或少相同的时间
我该如何处理这个问题?有什么方法可以在后台线程中从数千个彩色矩形创建 map ,然后立即在 UI 线程中显示它?
最佳答案
如果您已经尝试过 addPolygon()
和 GroundOverlay
,则还有两种可能性:
使用 Tile Overlays (首选);
在 MapView
上使用自定义绘图或 MapFragment
.
IMHO Tile Overlay 是一种更好的方式,因为它可能具有高性能 TileProvider
执行。例如,您可以为“低”缩放级别和“当前”(应在开始时向用户显示的级别)缩放级别创建图 block 并将它们存储在数组(HashMap
等)中或文件系统路径 ..\zoom_level\x\y\tile.png
如果有很多图 block 。还有更多“详细”图 block ,您可以在需要显示时“即时”创建(在单独的线程中),然后存储它们以备将来使用(如果需要)。当然,您需要自定义模块来快速读取 GeoJson
(类似于 Jackson)并将其呈现为 .png
磁贴。因此,似乎可以为您的情况创建 TileProvider
,通过性能和内存消耗进行优化。您可以使用 this answer的 Alex Vasilkov作为第一次迭代。
如果您选择自定义绘图,您应该覆盖 MapView
的 onDraw()
方法或 MapFragment
的 dispatchDraw()
>。就像在this answer .在那种情况下,您可以控制所有过程,但这种方式实现起来更加复杂。
更新:
您可以为 onCameraMove()
执行操作,如 this答案(那里使用的 GoogleMap
对象的一些棘手传递):
public class RadarMapView extends MapView implements OnMapReadyCallback {
private OnMapReadyCallback mMapReadyCallback;
private GoogleMap mGoogleMap;
private Marker mMarker;
private Paint mPaintRadar;
public RadarMapView(@NonNull Context context) {
super(context);
init();
}
public RadarMapView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RadarMapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public RadarMapView(@NonNull Context context, @Nullable GoogleMapOptions options) {
super(context, options);
init();
}
@Override
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
drawRadarOverTheMap(canvas);
canvas.restore();
}
private void drawRadarOverTheMap(Canvas canvas) {
if (mGoogleMap == null) {
return;
}
final float centerX = getX() + getWidth() / 2;
final float centerY = getY() + getHeight() / 2;
canvas.drawCircle(centerX, centerY, 150, mPaintRadar);
canvas.drawCircle(centerX, centerY, 300, mPaintRadar);
canvas.drawCircle(centerX, centerY, 450, mPaintRadar);
}
private void init() {
setWillNotDraw(false);
mPaintRadar = new Paint();
mPaintRadar.setColor(Color.GREEN);
mPaintRadar.setStyle(Paint.Style.STROKE);
mPaintRadar.setStrokeWidth(10);
}
@Override
public void getMapAsync(OnMapReadyCallback callback) {
mMapReadyCallback = callback;
super.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
invalidate(); // NB! Exactly this line you need
}
});
if (mMapReadyCallback != null) {
mMapReadyCallback.onMapReady(googleMap);
}
}
}
更新#2:
您可以制作多边形当前 View 的“屏幕截图”(不完全是屏幕截图,而是在位图上创建多边形图像)并在 onCameraMove()
中移动它(不是重绘所有多边形)。然后在 onCameraIdle()
中创建并显示新的全多边形 View 。此外,您可以创建比 map 屏幕 View 稍大的位图(用于缩小和正确滚动)。或者您可以“跳过”一些 onCameraMove()
调用(例如,每 3 个 onCameraMove()
调用调用一次 invalidate()
等) .
顺便说一句:如果是 Tile Overlays,移动和缩放是“开箱即用”的。您只需要创建一个棘手的 TileProvider。整个设备屏幕只需要生成几个图 block (单个图 block 的大小为 256x256)。因此,您可以为当前屏幕、currentZoomLevel-1、currentZoomLevel+1(在缩放的情况下)和向左、右、顶部和底部生成 + 2(或 3)个图 block (在滚动的情况下)。您还可以存储生成的图 block 以供将来在某些缓存(HashMap、LRU 等)中使用。并且您可以在单独的线程中生成“额外的”(当前不可见的)图 block 。
关于java - 将大型 GeoJson 添加到 Android 上的 GoogleMap 的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64416577/
我正在尝试按照此链接 http://bost.ocks.org/mike/map/ 上的教程进行操作到目前为止,我已经完全按照列出的每条说明进行操作,但是当我尝试运行“#Converting Data
何我可以反转一个国家的 GeoJson,以便它将国家定义为世界地图多边形中的一个洞?我需要这个来在 OpenLayers 5.3 中创建 GeoJson VectorLayer 的蒙版。 最佳答案 在
我在构建 GeoJSON 并将其放在 map 上的传单代码方面遇到了一些麻烦。 GeoJSON 是根据服务的 XML 响应构建的。 错误是 无效的 GeoJSON 对象。 throw new Erro
我有一个 geojson 表示插值天气数据的等高线层。某些轮廓在更高的缩放级别消失,如以下屏幕抓图所示。 将多边形作为图层添加到 Mapbox 时,使用以下代码: map.addSource('min
我有一些地理边界 have a GeoJSON endpoint for . 我还有一些变量存储在单独的 GeoJSON endpoint 中它没有坐标,但确实有我想稍后使用 D3 对 map 进行主
我是 MapBox GL Js 的新手,我想通过 https 调用一个大的 GeoJSON 文件并将其显示到 map 上。 我认为调用 vector Tile 是最好的方法,我找到了一些教程,展示了如
我已经使用 SQL 到 geoJSON 生成了我的数据库的一些兴趣点。 地理数据: { "FeatureCollection" : [ { "g
创建一张与此处找到的 map 类似的 map : https://www.plantmaps.com/interactive-california-2012-usda-plant-zone-hardi
我对 ammCharts 比较陌生,这也是我第一次尝试创建 geoJSON 文件。 以下是我的geoJson文件: GeoJSON file 这就是我要实现的目标: example 当我加载我的 ge
我有几个 geojson 层,并且我使用组将其分层。我使用此处找到的 Mike 答案将 map 集中在给定的 geojson 文件上 -> Center a map in d3 given a geo
环回新手,但设置我的第一个基于节点的 RestAPI 很有趣。我能够创建模型并在数据存储中创建关联的表。我的模型需要具有数据类型 geojson 的属性,即以下形式的字符串: { “类型”:“特征”,
我使用传单构建了一个 map ,其中包含大的 GeoJSON 区域,这些区域由多个“较小”的 GeoJSON 区域组成。 我正在使用 Leaftet-Ajax 来这样调用它们: var Rennes
我已经能够让其中的一部分工作,但是当 properties.affectedZones 有多个条目时,我的 jQuery 失败了。我已经使用 .each 努力显示受到红旗警告的受影响区域,但是当有两个
我需要对从 geojson 文件中提取的每个功能进行不同的样式设置。然而,这个匿名样式函数仅更改它遇到的第一个功能的样式并停止。我是传单新手。看过几个演示,但找不到这个匿名样式函数仅更改第一个功能的样
我有多个 geojson 类型:存储在 Mysql 中的 FeatureCollection。我想将两个或多个 geojson 合并到一个 FeatureCollection geojson 中并显示
我有这个 geojson { "type":"FeatureCollection", "features":[ { "type":"Feature",
我正在尝试在基于标准 HelloWorld 示例应用程序的测试应用程序中加载以下 geoJson 文件。 { "type": "FeatureCollection", "generator":
我正在使用 GeoJSON 数据构建传单 map 。尝试根据 GeoJSON 属性设置我使用的图标时遇到问题。我认为我的错误与使用字符串调用对象有关,但我无法弄清楚它到底是什么。 这是我的代码: Ge
我有包含如下地理字段的文档。 "geo" : { "type" : "Point", "coordinates" : [ 37.44609999, -1
是否可以仅使用 JavaScript(通过 d3、topojson 或任何其他方式)确定给定纬度、经度的 GeoJSON 点是否位于给定 GeoJSON 多边形内? 例如,我可以根据教程 here 绘
我是一名优秀的程序员,十分优秀!