【问题标题】:Draw WFS with latlong coordinates to canvas in Java用 latlong 坐标将 WFS 绘制到 Java 中的画布上
【发布时间】:2020-01-30 22:17:45
【问题描述】:

我是 Java 编程的新手,如果能提供任何帮助,我将不胜感激。 所以我想从 WFS 服务器在基于 Java 的画布(例如 JFrame、Processing)中显示一组经纬度坐标(超过 50 个坐标)。我设法解析了经纬度值并将其打印到控制台。现在我被困在如何将经纬度坐标带到屏幕坐标上(我想在 1000x500 大小上绘制它)。我试图搜索参考,但找不到像我这样的初学者最简单的参考。这是我的代码的当前部分:

String[] splitc = coord.split(",");
                    String lon = splitc[0];
                    String lat = splitc[1];
                    //parse string to float
                    float loncoord=Float.parseFloat(lon);
                    float latcoord=Float.parseFloat(lat);
  1. 我可以像https://docs.geotools.org/latest/userguide/library/referencing/axis.html 那样使用Geotools 库的world2screen.translate 将坐标从WFS 传输到屏幕坐标吗?
  2. 在处理中,有一个 map() 函数 (https://processing.org/reference/map_.html) 可以从一个范围转移到另一个范围。我已经尝试过了,但它在我的 IDE 上不起作用。
  3. 一个超级菜鸟问题,我正在尝试将 WFS 连接存储在一个函数中,以便可以在另一个类中调用它,我应该将它存储在静态 void 中还是使用“return”?

如果有人可以提供类似任务的示例,那将非常有帮助。谢谢(萨拉)

【问题讨论】:

    标签: java swing processing gis geotools


    【解决方案1】:
    1. 您可以改用这个公式:

      float x = ((WIDTH/360.0) * (180 + loncoord));
      float y = ((HEIGHT/180.0) * (90 - latcoord));
      
    2. 它应该可以工作...请注意,它返回 float 并接受 5 个形式的参数: map(input, inputMin, inputMax, outputMin, outputMax)

    3. 您只想创建一次连接,因此您有两个可行的选择:将连接定义为静态类的静态变量,或将连接定义为singleton 之后的类的实例变量模式。

      假设您选择了前一种方法,因此返回连接变量的方法应该是static,而不是void

      public static connectionType getConnection() {
          return connectionObject;
      }
      

      ...其中connectionType 是连接的数据类型。

    【讨论】:

    • 你能详细说明你的公式吗?我对 latlong 与屏幕坐标中的轴有点困惑
    【解决方案2】:

    最简单的方法是创建一个 GeoTools WFSDataStore,如果用户只提供了一个服务端点的 URL,此代码将构建 getCapabilities 字符串,并在需要时处理身份验证。数据存储存储在类的一个字段中:

      public FetchWFS(String url, String user, String passwd) throws IOException, URISyntaxException {
        if (!user.isEmpty()) {
          auth = true;
        }
        baseURL = new URL(url);
        List<NameValuePair> nvp = URLEncodedUtils.parse(baseURL.toURI(), "UTF-8");
        NameValuePair service = new BasicNameValuePair("service", "wfs");
        NameValuePair request = new BasicNameValuePair("request", "getCapabilities");
        NameValuePair version = new BasicNameValuePair("version", "2.0.0");
        HashMap<String, NameValuePair> parts = new HashMap<>();
        parts.put(service.getName(), service);
        parts.put(request.getName(), request);
        parts.put(version.getName(), version);
        for (NameValuePair part : nvp) {
    
          if (part.getName().equalsIgnoreCase("SERVICE")) {
            // We don't care what they think this should be
          } else if (part.getName().equalsIgnoreCase("REQUEST")) {
            // This must be getCapabuilities so we ignore them
          } else if (part.getName().equalsIgnoreCase("VERSION")) {
            System.out.println("Changing version to " + part.getValue());
            parts.put(version.getName(), part);
          } else {
            parts.put(part.getName(), part);
          }
        }
    
        URIBuilder builder = new URIBuilder();
        builder.setScheme(baseURL.getProtocol());
        builder.setHost(baseURL.getHost());
        builder.setPort(baseURL.getPort());
        builder.setPath(baseURL.getPath());
        List<NameValuePair> p = new ArrayList<>();
        p.addAll(parts.values());
        builder.setParameters(p);
        // builder.addParameter("viewparams", "q:\"mySolrQuery\"");
        URI uri = builder.build();
        System.out.println(uri);
        baseURL = uri.toURL();
        // fetch the DataStore
        Map<String, Object> params = new HashMap<>();
        params.put(WFSDataStoreFactory.URL.key, baseURL);
        // params.put(WFSDataStoreFactory.WFS_STRATEGY.key, "mapserver");
        if (auth) {
          params.put(WFSDataStoreFactory.USERNAME.key, user);
          params.put(WFSDataStoreFactory.PASSWORD.key, passwd);
        }
        // params.put(WFSDataStoreFactory.WFS_STRATEGY.key, "mapserver");
        datastore = DataStoreFinder.getDataStore(params);
      }
    

    一旦你有一个 DataStore(任何类型),你就可以获得一个可用的列表 featureTypes,然后将其中一个(或多个)添加到地图中:

            JMapFrame frame = new JMapFrame();
            MapContent map = new MapContent();
            String[] names = datastore.getNames();
            featureSource = store.getFeatureSource(names[0]); //fetch first featureType
            schema = featureSource.getSchema();
    
            Style style = SLD.createSimpleStyle(schema);
            this.layer = new FeatureLayer(featureSource, style);
    
            map.addLayer(layer);
            frame.enableToolBar(true);
            frame.setMinimumSize(new Dimension(800, 400));
            frame.setVisible(true);
    

    GeoToolsQuickstart Tutorial 将帮助您开始使用简单的映射,而Map Styling tutorial 将允许您生成更漂亮的地图,而不是简单的黑白默认地图。

    【讨论】:

    • 谢谢,但是我们可以使用 JMapframe 制作交互式地图吗?例如,如果用户点击该点,就会出现属性。
    • JMapFrame 工具栏包含一个默认执行此操作的“识别”工具。您当然可以在任何需要的地方重复使用该操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多