Нарисуйте WFS с координатами latlong на холст в Java

Я очень новичок в программировании на Java, буду признателен за любую помощь. Итак, я хочу отобразить набор координат по широте (более 50 координат) на холсте на основе Java (например, JFrame, Processing) с сервера WFS. Мне удалось разобрать значение lat-long и вывести его на консоль. Теперь я застрял в том, как привести координаты lat-long к координатам экрана (я хотел бы нарисовать его на размере 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. Могу ли я передать координаты из WFS в координаты экрана, используя world2screen.translate библиотеки Geotools, как в https://docs.geotools.org/latest/userguide/library/referencing/axis.html ?
  2. В обработке есть функция map() (https://processing.org/reference/map_.html) для перехода из одного диапазона в другой. Я пробовал это, но это не сработало в моей среде IDE.
  3. Один супер нубский вопрос: я пытаюсь сохранить соединение WFS в функции, чтобы я мог вызвать его в другом классе, должен ли я хранить его в static void или использовать «return»?

Если кто-то может привести пример аналогичной задачи, это было бы очень полезно. Спасибо (Сара)


person Sara Lee    schedule 30.01.2020    source источник


Ответы (2)


  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. Вы хотите создать соединение только один раз, поэтому у вас остается два возможных варианта: определение соединения как статической переменной статического класса или определение соединения как переменной экземпляра класса, следующего за одиночный шаблон.

    Предполагая, что вы выбрали первый подход, метод, который возвращает переменную соединения, должен быть static, но не void:

    public static connectionType getConnection() {
        return connectionObject;
    }
    

    ... где connectionType — тип данных соединения.

person micycle    schedule 31.01.2020
comment
не могли бы вы уточнить свою формулу? Я немного смущен осью в координатах широты и экрана. - person Sara Lee; 01.02.2020

Самый простой способ — создать GeoTools WFSDataStore, этот код создает строку getCapabilities, если пользователь предоставил только URL-адрес конечной точки службы, и при необходимости обрабатывает аутентификацию. Хранилище данных хранится в поле класса:

  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);
  }

Если у вас есть хранилище данных (любого типа), вы можете получить список доступных типов функций, а затем добавить один (или несколько) из них на карту:

        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);

GeoTools Краткое руководство поможет вам начать работу с простым картографированием, а Учебное пособие по стилю карты позволит вам создать более красивую карту, когда вам нужно нечто большее, чем простая черно-белая карта по умолчанию.

person Ian Turton    schedule 31.01.2020
comment
Спасибо, а можно сделать интерактивную карту с помощью JMapframe? Например, если пользователь щелкнет точку, атрибуты появятся. - person Sara Lee; 01.02.2020
comment
Панель инструментов JMapFrame включает инструмент идентификации, который делает это по умолчанию. Конечно, вы можете повторно использовать это действие в любом месте, где вам это нужно. - person Ian Turton; 01.02.2020