[GIS] Architecture for Java EE application

javaopenlayers-2postgisweb-mappingwms

I´m new to GIS development. I have read about Openlayers, maps servers (I choose Geoserver), geodatabase (in my case i choose PostGIS) and theory of GIS in general. I´m developing a Java EE application that needs GIS functionality, but i´m having some problems defining the high level architecture for my requirements. Before i explain what alternatives i´m considering, i think it´s best if I give the main requirements that the present application must fulfill:

  • It has to show a map on the browser, with several layers. Among the features that it has to show, are points that represents cities, or users, etc. In some of this features the user is allowed to click and a pop up should appear with related information, and effects like that.

  • For some of the layers, the users may see only some information (i.e, some of the features) but not all, and this is based on some custom domain logic that its implemented server side with java EE.

  • The users can modify some map information. They may create certain new features or modify existing ones, but all of these is based on custom logic implemented server side. They can also move through the map, and other users should be capable of seeing this updates.

So, i have a lot of questions regarding how i should design something like this. My first question is:

  • Should i use WMS or WFS services? As the users will be modifying things on the map, i first think of using WFS services. But, remember that all the operations that modify the map require specific domain logic in order to validate the update, before hitting in the data store. So perhaps i can access directly into the database from java and let the user retrieve the map from a WMS service. At the same time, i´m not so sure about this, because then i´ll be hitting the data base from two sides (Geoserver and jdbc or jpa or whatever) and i don´t know what kinds of problems could arise.

  • Lets suppose i pick one of the previous services. How could be client-side logic be implemented? I think that with Ajax i can request the application to see if i can validate the operation on the map, and if the validation is succesful then make a call with Openlayers to the service in Geoserver (i don´t know if this is good, since the client ends up making two remote calls, one to the java EE app and other to Geoserver in order to retrieve the ¨results¨ (map)). Or how can i accomplish this? Thinking about this i´m not even sure about why I should be using a map server at all, since i have to do some geographical validations in the map before serving the geographical information.. perhaps i can just query PostGIS and serve the contents directly to openlayers through the ajax call if the previous validations pass? or is it possible to pass the validation logic to geoserver somehow?

As you can see, these are some fundamental questions and decisions I have to made before doing anything else, and I was hoping for advice and other alternatives as well.

Best Answer

Dont be complicated if you can be simple.

1) Client-side: pure jQuery and html. JSON + Ajax to communicate with server.

function loadCities() {
    var mapbounds = map.getExtent();
    mapbounds.transform(toProjection, fromProjection );
    bbox = mapbounds.toArray();
    var bleft = bbox[0];
    var bbottom = bbox[1];
    var bright = bbox[2];
    var btop = bbox[3];
    showLoader();
    var origem = "getCities?bleft=" + bleft + "&bbottom=" + bbottom + "&bright=" + bright + "&btop=" + btop;
    $.ajax({
            url: origem,
            dataType: "json"
    }).always(function() { hideLoader(); }).done(function(data) {
        data = eval( data );
        var geojson_format = new OpenLayers.Format.GeoJSON({
            'internalProjection': map.baseLayer.projection,
            'externalProjection': new OpenLayers.Projection("EPSG:4326")
        });
        citiesLayer.removeAllFeatures();
        citiesLayer.addFeatures(geojson_format.read(data));
    });     
}

2) Server side: Struts Actions configured to JSON responses:

    @Action(value="getCities", results= {  
            @Result(name="ok", type="httpheader", params={"status", "200"}) }
    )  

@ParentPackage("default")
public class GetCitiesAction  {

    public String execute(){
    HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);  
    Double bleft = Double.parseDouble( request.getParameter("bleft") );
    Double bbottom = Double.parseDouble( request.getParameter("bbottom") );
    Double bright = Double.parseDouble( request.getParameter("bright") );
    Double btop = Double.parseDouble( request.getParameter("btop") );
    int idUsuario = Integer.valueOf( request.getParameter("idUsuario") );

    String resposta = "";

        try {
            CityController cc = new CityController( idUsuario );
            IStaticElementList lista = cc.getCitiesInBBOX( bleft, bbottom, bright, btop );
            resposta = lista.asJson();
        } catch ( Exception e ) {
            e.printStackTrace();
        }

        try { 
            HttpServletResponse response = (HttpServletResponse)ActionContext.getContext().get(StrutsStatics.HTTP_RESPONSE);
            response.setCharacterEncoding("UTF-8"); 
            response.getWriter().write(resposta);  
        } catch (IOException ex) {  
            ex.printStackTrace();
        }

        return "ok";
       }
 }

Hybernate to database access. Don't forget to keep the domains. See Domain Driven Design. Mail me if in doubt (see my profile).

enter image description here

Related Question