在带有 GeoServer 的 Android 应用程序中使用 getTileURL

2023-11-26

我们刚刚开始在 Android 上使用 Google 地图,并设置了一个 GeoServer 来提供我们想要添加为地图上叠加层的图块。到目前为止,我已经遵循了一些教程和参考资料来入门。

  • 用于获取“我的位置”
  • 在 Android 上设置 WMS
  • 仓库管理系统参考

问题:虽然我在中生成的网址getTileUrl函数在TileProviderFactory当我设置断点并将 URL 复制并粘贴到浏览器中时,确实会返回 png 图像,但它不会作为 Android 设备上的叠加层加载到地图上。从我所看到的和阅读后没有抛出任何错误this我不确定是否会有任何错误,因为他们已经表明错误已被消除。

我想知道什么如果您可以在我的代码中看到任何直接问题或有任何调试建议,我将能够判断应用程序是否确实与我的地理服务器通信以检索图像。我查看了 GeoServer 上的日志,似乎只有我的浏览器请求正在通过,并且没有收到来自 Android 的任何请求(这有点难以判断,因为我们还有其他应用程序也在使用该服务器)。 Android 手机通过 wifi 和手机连接,并启用 GPS。作为最后的手段,我尝试更改图块覆盖 zIndex 并将其设置为可见,但这似乎没有任何区别。

编辑:此时 Android 设备绝对没有与 GeoServer 通信。

编辑2:能够从网站加载静态图像 (喜欢this)作为覆盖层,发现我在测试对形成的 URL 的 HTTP 请求时遇到以下异常:

W/System.err(10601): java.net.SocketException: The operation timed out
W/System.err(10601): at org.apache.harmony.luni.platform.OSNetworkSystem
     .connectStreamWithTimeoutSocketImpl(Native Method)
W/System.err(10601): at org.apache.harmony.luni.net.PlainSocketImpl
     .connect(PlainSocketImpl.java:244)
W/System.err(10601): at org.apache.harmony.luni.net.PlainSocketImpl
     .connect(PlainSocketImpl.java:533)
W/System.err(10601): at java.net.Socket
     .connect(Socket.java:1074)
W/System.err(10601): at org.apache.http.conn.scheme.PlainSocketFactory
     .connectSocket(PlainSocketFactory.java:119)

Thanks.

地图测试活动

public class MapTestActivity extends FragmentActivity
    implements LocationListener, LocationSource{

    private GoogleMap mMap;
    private OnLocationChangedListener mListener;
    private LocationManager locationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_test);     
        setupLocationManager();     
        setupMapIfNeeded();
    }

    private void setupLocationManager() {
        this.locationManager = 
            (LocationManager) getSystemService(LOCATION_SERVICE);

        if (locationManager != null) {
            boolean gpsIsEnabled = locationManager.isProviderEnabled(
                    LocationManager.GPS_PROVIDER);
            boolean networkIsEnabled = locationManager.isProviderEnabled(
                    LocationManager.NETWORK_PROVIDER);

            if(gpsIsEnabled) {
                this.locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, 5000L, 10F, this);
            }
            else if(networkIsEnabled) {
                this.locationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, 5000L, 10F, this);
            }
            else {
                //Show an error dialog that GPS is disabled...
            }
        }
        else {
            // Show some generic error dialog because 
            // something must have gone wrong with location manager.
        }
    }

    private void setupMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
            mMap.setLocationSource(this);
        }
    }

    private void setUpMap() {
        // TODO Auto-generated method stub
        mMap.setMyLocationEnabled(true);
        TileProvider geoServerTileProvider = TileProviderFactory
            .getGeoServerTileProvider();
        TileOverlay geoServerTileOverlay = mMap.addTileOverlay(
            new TileOverlayOptions()
                .tileProvider(geoServerTileProvider)
                .zIndex(10000)
                .visible(true));
    }
    // Non-relevant listener methods removed
}

TileProviderFactory

public class TileProviderFactory {

    public static GeoServerTileProvider getGeoServerTileProvider() {

        String baseURL = "mytileserver.com";
        String version = "1.3.0";
        String request = "GetMap";
        String format = "image/png";
        String srs = "EPSG:900913";
        String service = "WMS";
        String width = "256";
        String height = "256";
        String styles = "";
        String layers = "wtx:road_hazards";

        final String URL_STRING = baseURL + 
                "&LAYERS=" + layers + 
                "&VERSION=" + version + 
                "&SERVICE=" + service + 
                "&REQUEST=" + request + 
                "&TRANSPARENT=TRUE&STYLES=" + styles + 
                "&FORMAT=" + format + 
                "&SRS=" + srs + 
                "&BBOX=%f,%f,%f,%f" + 
                "&WIDTH=" + width + 
                "&HEIGHT=" + height;


        GeoServerTileProvider tileProvider = 
            new GeoServerTileProvider(256,256) {

            @Override
            public synchronized URL getTileUrl(int x, int y, int zoom) {
                try {       

                    double[] bbox = getBoundingBox(x, y, zoom);

                    String s = String.format(Locale.US, URL_STRING, bbox[MINX], 
                            bbox[MINY], bbox[MAXX], bbox[MAXY]);

                    Log.d("GeoServerTileURL", s);

                    URL url = null;

                    try {
                        url = new URL(s);
                    } 
                    catch (MalformedURLException e) {
                        throw new AssertionError(e);
                    }

                    return url;
                }
                catch (RuntimeException e) {
                    Log.d("GeoServerTileException", 
                        "getTile x=" + x + ", y=" + y + 
                        ", zoomLevel=" + zoom + 
                        " raised an exception", e);
                    throw e;
                }

            }
        };
        return tileProvider;
    }
}

GeoServerTileProvider

public abstract class GeoServerTileProvider extends UrlTileProvider{

    // Web Mercator n/w corner of the map.
    private static final double[] TILE_ORIGIN = 
        {-20037508.34789244, 20037508.34789244};
    //array indexes for that data
    private static final int ORIG_X = 0; 
    private static final int ORIG_Y = 1; // "

    // Size of square world map in meters, using WebMerc projection.
    private static final double MAP_SIZE = 20037508.34789244 * 2;

    // array indexes for array to hold bounding boxes.
    protected static final int MINX = 0;
    protected static final int MINY = 1;
    protected static final int MAXX = 2;
    protected static final int MAXY = 3;

    public GeoServerTileProvider(int width, int height) {
        super(width, height);
    }

    // Return a web Mercator bounding box given tile x/y indexes and a zoom
    // level.
    protected double[] getBoundingBox(int x, int y, int zoom) {
        double tileSize = MAP_SIZE / Math.pow(2, zoom);
        double minx = TILE_ORIGIN[ORIG_X] + x * tileSize;
        double maxx = TILE_ORIGIN[ORIG_X] + (x+1) * tileSize;
        double miny = TILE_ORIGIN[ORIG_Y] - (y+1) * tileSize;
        double maxy = TILE_ORIGIN[ORIG_Y] - y * tileSize;

        double[] bbox = new double[4];
        bbox[MINX] = minx;
        bbox[MINY] = miny;
        bbox[MAXX] = maxx;
        bbox[MAXY] = maxy;
        return bbox;
    }
}

事实证明这是一个网络问题,与我的“正确”实现完全无关。我想这个问题对于其他开始使用 Android + GeoServer 实现的人来说将是一个很好的例子,所以我将保留它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在带有 GeoServer 的 Android 应用程序中使用 getTileURL 的相关文章

  • EditText 中的验证允许 IP 或 Web Url 主机

    我需要对我的 EditText 进行验证 以便它允许我输入有效的 IP 地址格式 即示例 132 0 25 225 or 网址格式 www 例如 www example com 逻辑是 如果用户首先输入任何数值 则验证 IP 将执行操作 否
  • Android KeyBoard.Key 禁用图标 预览特殊键?

    我通过实现 KeyboardView OnKeyboardActionListener 接口来自定义自己的软键盘 按下按键时 将显示预览弹出窗口 我的问题是如何禁用 SHIFT 和 DELETE 等特殊键的预览弹出窗口 我尝试将 andro
  • Android 上的 Firebase:如何检查 Firebase 身份验证失败原因?

    我在 Android 上使用 Firebase 和 Firebase Auth 功能 I try FirebaseAuth signInWithEmailAndPassword如果失败 我想知道为什么登录过程失败 The signInWit
  • 使用 APDU 命令的有效 NFC 读取比特率是多少?

    我目前正在使用 Android IsoDep trancieve 函数发送和接收累计 1628 字节的数据 该函数分布在 35 个 APDU 命令 选择应用程序 身份验证 读取 中 字节计数包括返回的 MAC 校验和以及由 transcie
  • 应用程序实例是否始终在任何活动之前创建?

    在 Android 中 您可以通过扩展 Application 类并在 Manifest 中声明名称来提供您自己的 Application 类实现 我的问题是 这个实现是否总是在初始活动之前创建 或者活动可以在应用程序实例有时间创建之前启动
  • Google Firebase - 如何删除崩溃报告?

    我最终失明了吗 还是没有明显的方法可以通过 Google Firebase Web 控制台删除 Firebase 崩溃报告 我的 Android 应用程序已成功记录报告 但现在出现大量 开发崩溃 占用了我在控制台中的大部分视图 这使得找到实
  • Android Lollipop prepareAsync() 需要很长时间才能返回

    在 Samsung Galaxy Note 4 上的 Android Lollipop 几周前刚刚从 4 4 4 更新 上 prepareAsync 几乎需要 20 秒来加载实时流 在 4 4 4 上 只需要 2 3 秒 并且没有错误 见下
  • 按钮未显示在屏幕上

    我创建了一个应用程序 其中显示带有图像和文本的列表视图 我在页面末尾添加按钮 但这没有显示在屏幕上 我是 Android 新手 我该如何解决这个问题 这是我的 UI XML 代码
  • 连接到不可发现的蓝牙设备

    我正在开发一个安卓应用程序 只是一个一般性问题 是否可以连接到公开不可发现的设备 提前致谢 如果您之前已与该设备配对 则即使该设备未处于可发现模式 也可以再次连接到该设备 参见这篇文章 以编程方式连接到配对的蓝牙设备 https stack
  • 为什么按钮上的 maxWidth 不起作用以及如何解决它?

    我的布局上有两个按钮 在大屏幕设备 平板电脑 上我想限制它们的宽度 这样它们看起来就不会很荒谬 我希望使用 maxWidth 属性 但它显然在我的场景中没有任何作用 这是布局定义 按钮使用布局的整个宽度 忽略 maxWidth 中的任何值
  • 使用 Android 播放任意音调

    有没有办法让Android发出任意频率的声音 意思是 我不想预先录制声音文件 我环顾四周 音调发生器 http developer android com reference android media ToneGenerator html
  • 获取可以共享数据的应用程序列表

    此代码显示默认共享对话框 Intent sharingIntent new Intent Intent ACTION SEND sharingIntent setType text html sharingIntent putExtra a
  • AnalyticsService 未在应用程序清单中注册 - 错误

    我正在尝试使用 sdk 中提供的以下文档向 Android 应用程序实施谷歌分析服务 https developers google com analytics devguides collection android v4 https d
  • Android ListView setSelection() 似乎不起作用

    我有一个ListActivity实现onListItemClick 并调用doSomething 类的功能 后者包含l setSelection position where l is the ListView object 现在有一个on
  • window.onbeforeunload 在 Android Chrome 上不会触发 [alt.解决方案?]

    我开发了一个简单的聊天应用程序 我正在使用 window onbeforeunload当有人关闭选项卡 浏览器时 基本上是当用户离开房间时 通知其他用户 这是我的代码 scope onExit function scope chatstat
  • jar 中的 apklib 有什么优点?

    我正在关注这个问题 https stackoverflow com questions 6059502 whats the difference between apklib and jar files但它并没有完全回答我的问题 jar 中
  • android 中camera.setParameters 失败

    我已将相机功能包含在我的应用程序中 我还在市场上推出了该应用程序 我从一位用户那里收到一条错误消息 称他在打开相机时遇到错误 我已经在 2 1 的设备上测试了该应用程序 我从用户那里得到的错误是使用 Nexus One 它主要运行 2 2
  • ACCESS_BACKGROUND_LOCATION 不适用于低于 Q (29) 的 Android 版本

    我的应用程序面向 Android API 28 根据文档 https developer android com preview privacy location target android 10 我应该要求ACCESS BACKGROU
  • 如何在Android中解析xml类型的HTTPResponse

    我有一个 Android 应用程序 我使用 POST 方法来获取响应 这是我的代码 HttpResponse httpResponse httpclient execute httppost HttpEntity resEntity htt
  • Android ADT Eclipse 插件,parseSDKContent 失败

    我刚刚设置了我的第一个 Android 开发环境 其中包括 日食3 5 Mac OS X 10 5 适用于 x86 mac 的 Android SDK ADT Eclipse 插件 0 9 6 我已将 set PATH 设置为我的 SDK

随机推荐

  • 如何修复自定义 github 页面域上的 ERR_TOO_MANY_REDIRECTS?

    所以我一天前在 namecheap 上设置了自定义域的 github 页面没有问题 然后我尝试通过github新增加的页面对https的支持切换到Https 经过太多的挫折后 我切换到 CloudFlare for Https 但现在遇到错
  • JavaScript 中的 Zip 数组?

    我有 2 个数组 var a 1 2 3 var b a b c 我想要得到的结果是 1 a 2 b 3 c 这看起来很简单 但我就是想不出来 我希望结果是一个数组 其中两个数组中的每个元素都压缩在一起 Use the map方法 var
  • 将电话号码与 Firebase 网页版中的 Facebook 和 Gmail 帐户关联

    我正在使用 Firebase 服务在 React 中创建一个 Web 应用程序 我在登录屏幕上登录了 Google 和 Facebook 登录后用户可以选择链接他们的手机 我使用 Firebase电话验证为了这 用户已经签名 然后他们使用手
  • DB单元应该忽略行的顺序

    有没有办法告诉 DB Unit 忽略行比较的顺序 我的问题是 我不知道行将以何种顺序写入数据库 但 DB Unit 强迫我给出一个有序列表 我想要 dbunit 做的是 检查数据库中的行数和预期数据集是否匹配 已解决 开箱即用 检查每行是否
  • 当代码编译良好时,Resharper“无法解析符号”[重复]

    这个问题在这里已经有答案了 我相信 错误消息与Serilog具体来说 而是因为代码 程序集 包的特定结构 修饰符等 所以 问题是Resharper显示错误 并且代码 来自引用的程序集 无法导航到 Visual Studio导航 通过Go t
  • jQuery.fn.load() 已弃用?

    jQuery fn load 在 jquery 3 X X 中已弃用 我把文档搞得一团糟 我的代码是 myDiv load mypage html 如何将 mypage html 加载到 myDiv 中 你的代码是正确的 这加载方法您使用的
  • python-requests:获取响应内容的头部而不消耗全部内容

    使用 python requests 和 python magic 我想测试 Web 资源的 mime 类型 而不获取其所有内容 特别是如果该资源恰好是 ogg 文件或 PDF 文件 根据结果 我可能决定全部获取 然而 在测试 mime 类
  • 如何在同一选择器上使用“&”和标签

    我正在尝试编写一个嵌套选择器 它选择具有特定属性的特定标签 例如 li 要选择此选项 li foo bar 可以 但我想把它嵌套在下面 foo bar 使用scss 符号 因为我还有其他东西 foo bar 属性 例如 div class
  • 用于过滤 @OneToMany 关联结果的注释

    我有两个表之间的父 子关系 以及我的 Java 类中的相应映射 这些表格大致如下所示 A ref number stuff varchar2 4000 B a ref number other number foo varchar2 200
  • 使用 React 动态加载样式表

    我正在构建一个 CMS 系统来管理营销登陆页面 在 编辑登陆页面 视图上 我希望能够加载用户正在编辑的任何登陆页面的关联样式表 我怎样才能用 React 做这样的事情呢 我的应用程序是完全 React 同构的 运行在Koa 我的相关页面的基
  • 如何从 Chrome 中的文件输入中删除“未选择文件”工具提示?

    我想从 Google Chrome 中的文件输入中删除 未选择文件 工具提示 我发现 Firefox 中没有显示任何工具提示 请注意 我不是在谈论输入字段内的文本 而是在谈论将鼠标移到输入上方时出现的工具提示 我尝试过这个但没有运气 myF
  • 编译错误:请求非结构或联合中的成员

    Edit 由于问题已经解决 下面的代码已被修改为可以工作 具体来说 hardwareList next item gt next最初是不带括号的 例如 hardwareList next item gt next 并且编译器不理解它 我正在
  • 图像标签下方的神秘空白[重复]

    这个问题在这里已经有答案了 我刚刚更改了网站上的标题图像 div style width 100 所以图像会按现在的比例缩小 但现在我有这个神秘的 10px 左右的间隙 我检查了 Chrome 中的检查器 但我看不出是什么导致了这个空间 我
  • 如何在 Three.js 中使用 GLTF Loader?纹理和材质显示为黑色

    我在加载 gltf 时遇到问题 该模型能够成功加载 但所有纹理和材质 已嵌入 gltf 中 都是全黑的 当我在 gltfviewer 中查看它时 所有纹理和材质都正确显示 我是 Three js 的新手 所以如果有人可以指导我使用 GLTF
  • 如何将 ArrayField 定义为 django 表单

    如何以django形式定义ArrayField 我有一些函数参数 我想为其添加验证 因此我创建了一个表单 其中一个函数参数是列表 我如何在表格中定义它 from django contrib postgres fields import A
  • Angular - 根据同级 RouterLinkActive 将样式应用于元素?

    我的应用程序上不仅有一个菜单栏需要在用户导航时绘制 我还有另一个组件也需要绘制 我可以通过使用来实现这一点吗routerLinkActive 菜单 html menu a option1 a a option2 a menu 这个菜单效果很
  • 如何在jquery上一一显示每个div?

    嘿 我不想在我的页面上制作很酷的效果 我在想 如何在加载时隐藏所有内容并一一显示每个 div 的效果 如果这是一个坏主意 你能帮我想出一个更好的主意吗 编辑 使用 div each jQuery 函数 EDIT2 孩子们的孩子 EDIT3
  • 如何使用rails3将本地时区的日期保存到数据库?

    我有 Rails3 应用程序 其模型用户和字段 expires at 创建如下 t column expires at timestamp 在我的数据库 postgresql 中 它的类型为 timestamp without timezo
  • Ruby 中如何实现多态性?

    在 C 中 我可以这样做 class Program static void Main string args List
  • 在带有 GeoServer 的 Android 应用程序中使用 getTileURL

    我们刚刚开始在 Android 上使用 Google 地图 并设置了一个 GeoServer 来提供我们想要添加为地图上叠加层的图块 到目前为止 我已经遵循了一些教程和参考资料来入门 用于获取 我的位置 在 Android 上设置 WMS