Package org.geomajas.plugin.geocoder.command.geocoder

Source Code of org.geomajas.plugin.geocoder.command.geocoder.GetLocationForStringCommand

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.plugin.geocoder.command.geocoder;

import com.vividsolutions.jts.geom.Envelope;
import org.geomajas.annotation.Api;
import org.geomajas.command.Command;
import org.geomajas.geometry.Bbox;
import org.geomajas.geometry.Coordinate;
import org.geomajas.geometry.Crs;
import org.geomajas.global.ExceptionCode;
import org.geomajas.global.GeomajasException;
import org.geomajas.plugin.geocoder.api.CombineResultService;
import org.geomajas.plugin.geocoder.api.GeocoderInfo;
import org.geomajas.plugin.geocoder.api.GeocoderService;
import org.geomajas.plugin.geocoder.api.GetLocationResult;
import org.geomajas.plugin.geocoder.api.SplitGeocoderStringService;
import org.geomajas.plugin.geocoder.command.dto.GetLocationForStringAlternative;
import org.geomajas.plugin.geocoder.command.dto.GetLocationForStringRequest;
import org.geomajas.plugin.geocoder.command.dto.GetLocationForStringResponse;
import org.geomajas.plugin.geocoder.service.CombineUnionService;
import org.geomajas.plugin.geocoder.service.GeocoderUtilService;
import org.geomajas.plugin.geocoder.service.SplitCommaReverseService;
import org.geomajas.service.DtoConverterService;
import org.geomajas.service.GeoService;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

/**
* Geocoder command which allows getting the location and/or area for a string location description.
*
* @author Joachim Van der Auwera
* @since 1.0.0
*/
@Api
@Component
public class GetLocationForStringCommand implements Command<GetLocationForStringRequest, GetLocationForStringResponse> {

  @Autowired
  private GeocoderInfo geocoderInfo;

  @Autowired
  private SplitCommaReverseService defaultSplitGeocoderStringService;

  @Autowired
  private CombineUnionService defaultCombineResultService;

  @Autowired
  private DtoConverterService dtoConverterService;

  @Autowired
  private GeocoderUtilService geocoderUtilService;

  @Autowired
  private GeoService geoService;

  /** {@inheritDoc} */
  public GetLocationForStringResponse getEmptyCommandResponse() {
    return new GetLocationForStringResponse();
  }

  /** {@inheritDoc} */
  public void execute(GetLocationForStringRequest request, GetLocationForStringResponse response) throws Exception {
    String location = request.getLocation();
    if (null == location) {
      throw new GeomajasException(ExceptionCode.PARAMETER_MISSING, "location");
    }
    String crsString = request.getCrs();
    if (null == crsString) {
      throw new GeomajasException(ExceptionCode.PARAMETER_MISSING, "crs");
    }
    Locale locale = null;
    if (null != request.getLocale()) {
      locale = new Locale(request.getLocale());
    }
    int maxAlternatives = request.getMaxAlternatives();

    Crs crs = geoService.getCrs2(crsString);

    SplitGeocoderStringService splitGeocoderStringService = geocoderInfo.getSplitGeocoderStringService();
    if (null == splitGeocoderStringService) {
      splitGeocoderStringService = defaultSplitGeocoderStringService;
    }
    CombineResultService combineResultService = geocoderInfo.getCombineResultService();
    if (null == combineResultService) {
      combineResultService = defaultCombineResultService;
    }

    List<String> locationList = splitGeocoderStringService.split(location);

    List<GetLocationResult> results = new ArrayList<GetLocationResult>();
    List<GetLocationResult[]> alternatives = new ArrayList<GetLocationResult[]>();
    Pattern namePattern = getShouldUsePattern(request.getServicePattern());
    for (GeocoderService geocoderService : geocoderInfo.getGeocoderServices()) {
      if (shouldUse(namePattern, geocoderService.getName())) {
        GetLocationResult[] result = geocoderService.getLocation(locationList, maxAlternatives, locale);
        if (null != result && result.length > 0) {
          for (GetLocationResult aResult : result) {
            aResult.setGeocoderName(geocoderService.getName());

            CoordinateReferenceSystem sourceCrs = geocoderService.getCrs();
            Envelope envelope = aResult.getEnvelope();

            // point locations needs to converted to an area based on configuration settings
            if (null == envelope) {
              envelope = geocoderUtilService.extendPoint(aResult.getCoordinate(), sourceCrs,
                  geocoderInfo.getPointDisplayWidth(), geocoderInfo.getPointDisplayHeight());
            }

            // result needs to be CRS transformed to request CRS
            aResult.setEnvelope(geocoderUtilService.transform(envelope, sourceCrs, crs));
          }
          if (result.length > 1) {
            alternatives.add(result);
          } else {
            results.add(result[0]);
          }
          if (!geocoderInfo.isLoopAllServices()) {
            break;
          }
        }
      }
    }

    response.setLocationFound(false);
    if (!results.isEmpty()) {
      response.setLocationFound(true);

      // combine match strings, default to search string unless we know we can do better
      String matchedLocation = location;
      String geocoderName = null;
      if (results.size() == 1) {
        List<String> matchedStrings = results.get(0).getCanonicalStrings();
        if (null != matchedStrings) {
          matchedLocation = splitGeocoderStringService.combine(matchedStrings);
        }
        geocoderName = results.get(0).getGeocoderName();
      }
      response.setCanonicalLocation(matchedLocation);
      response.setGeocoderName(geocoderName);

      // combine the user data, only when there is just one result
      if (results.size() == 1) {
        response.setUserData(results.get(0).getUserData());
      }

      // combine location envelopes
      Envelope resultEnvelope = combineResultService.combine(results);
      Bbox bbox = dtoConverterService.toDto(resultEnvelope);
      response.setBbox(bbox);
      response.setCenter(new Coordinate(bbox.getX() + bbox.getWidth() / 2, bbox.getY() + bbox.getHeight() / 2));
    } else {
      List<GetLocationForStringAlternative> altList = new ArrayList<GetLocationForStringAlternative>();
      response.setAlternatives(altList);
      for (GetLocationResult[] altArr : alternatives) {
        for (GetLocationResult alt : altArr) {
          if (maxAlternatives > 0 && maxAlternatives <= altList.size()) {
            break;
          }
          GetLocationForStringAlternative one = new GetLocationForStringAlternative();

          String matchedLocation = location;
          List<String> matchedStrings = alt.getCanonicalStrings();
          if (null != matchedStrings) {
            matchedLocation = splitGeocoderStringService.combine(matchedStrings);
          }
          one.setCanonicalLocation(matchedLocation);

          // set additional info data
          one.setGeocoderName(alt.getGeocoderName());
          one.setUserData(alt.getUserData());

          // combine location envelopes
          Bbox bbox = dtoConverterService.toDto(alt.getEnvelope());
          one.setBbox(bbox);
          one.setCenter(
              new Coordinate(bbox.getX() + bbox.getWidth() / 2, bbox.getY() + bbox.getHeight() / 2));

          altList.add(one);
        }
      }
    }

  }

  private Pattern getShouldUsePattern(String namePattern) {
    if (null == namePattern) {
      return null;
    }
    if (!namePattern.startsWith("^")) {
      namePattern = "^" + namePattern;
    }
    if (!namePattern.endsWith("$")) {
      namePattern = namePattern + "$";
    }
    if ("^.*$".equals(namePattern)) {
      return null;
    }
    return Pattern.compile(namePattern, Pattern.CASE_INSENSITIVE);
  }

  private boolean shouldUse(Pattern namePattern, String serviceName) {
    return null == namePattern || namePattern.matcher(serviceName).matches();
  }
}
TOP

Related Classes of org.geomajas.plugin.geocoder.command.geocoder.GetLocationForStringCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.