<file_sep>package com.robocorp2.core.dijkstra;

import java.util.List;

public class Graphe {

	private final List<Sommet> vertexes;
	  private final List<Arc> edges;

	  public Graphe(List<Sommet> vertexes, List<Arc> edges) {
	    this.vertexes = vertexes;
	    this.edges = edges;
	  }

	  public List<Sommet> getVertexes() {
	    return vertexes;
	  }

	  public List<Arc> getEdges() {
	    return edges;
	  }
    
}<file_sep># mock-server

## 1. Setup

Pour faire fonctionner le mock-serveur :
1. 
  a. Installer node.js : https://nodejs.org/download/
  b. Sous linux : https://www.digitalocean.com/community/tutorials/how-to-compile-node-js-with-npm-from-source-on-centos-6
2. Installer Sails.js : sudo npm install -g sails.js


a [Sails](http://sailsjs.org) application
<file_sep>package com.robocorp2.DAO;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slim3.datastore.Datastore;

import com.google.appengine.api.datastore.Key;
import com.robocorp2.meta.parking.ParkingMeta;
import com.robocorp2.model.parking.Parking;
import com.robocorp2.model.parking.PointGPS;
import com.robocorp2.model.parking.stats.ParkingForStats;

/**
 * Singleton access to Parking storage
 * @author Mathieu
 *
 */
public class ParkingDAO {

	private static ParkingDAO _instance =  new ParkingDAO();
	
	private ParkingDAO(){
		
	}
	
	/**
	 * Singleton implementation
	 * @return
	 */
	public static ParkingDAO getInstance(){
		return _instance;
	}
	
	/**
	 * Return a parking with his key
	 * @param key
	 * @return
	 */
	public Parking getParkingByKey(Key key){
		return Datastore.get(ParkingMeta.get(), key);
	}
	
	/**
	 * Search a parking with his name. Returns a list of parkings
	 * @param name
	 * @return
	 */
	public List<Parking> getParkingByName(String name){
		List<Parking> parkings = Datastore.query(ParkingMeta.get()).filter(ParkingMeta.get().nom.equal(name)).asList();
		return parkings;
	}
	
	/**
	 * Search a parking with his GPS point. Return a single parking or null.
	 * 
	 * @param gps
	 * @return
	 */
	public Parking getParkingByPointGPS(PointGPS gps){
		List<Parking> parkings = Datastore.query(ParkingMeta.get()).filter(ParkingMeta.get().pointGPSLat.equal(gps.getX()))
				.filter(ParkingMeta.get().pointGPSLon.equal(gps.getY())).asList();
		if(parkings.size() == 0){
			return null;
		}else{
			return parkings.get(0);
		}
	}
	
	/**
	 * Search a parking around a GPS point. Return a single parking.
	 * 
	 * @param gps
	 * @return
	 */
	public List<Parking> searchParkingsByPointGPS(PointGPS gps){
		List<Parking> parkings = Datastore.query(ParkingMeta.get()).sort(ParkingMeta.get().pointGPSLat.asc).sort(ParkingMeta.get().pointGPSLon.asc).asList();
		
		List<Parking> nearestParkings = new ArrayList<Parking>();
		int parkingsToFind = 5;
		if(parkings.size() < parkingsToFind){
			parkingsToFind = parkings.size();
		}
		for(int i = 0 ; i < parkingsToFind ; i ++){
			
		Parking nearestParking = new Parking(null, "test", "test", new PointGPS(Double.MAX_VALUE, Double.MAX_VALUE));
		for(Parking parking : parkings){
			if( Math.abs(parking.getPointGPSLat()-gps.getX()) < Math.abs(nearestParking.getPointGPSLat()-gps.getX()) &&
					Math.abs(parking.getPointGPSLon()-gps.getY()) < Math.abs(nearestParking.getPointGPSLon()-gps.getY())){
				nearestParking = parking;
				nearestParkings.add(parking);
				//parkings.remove(parking);
			}
		}
		}
		
		return nearestParkings;
	}
	
	/**
	 * Put a parking to datastore. Generate key before
	 * @param parking
	 * @return key
	 */
	public Key saveParking(Parking parking){
		Datastore.put(parking);
		return parking.getKey();
	}
	
	/**
	 * Save a modified parking
	 * @param key, parking
	 * @return parking
	 */
	public Parking editParking(Key key, Parking parking){
		parking.setKey(key);
		Datastore.delete(key);
		Datastore.put(parking);
		return parking;
	}
	
	/**
	 * Save a parking and keep a history of the previous state
	 * @param key
	 * @param parking
	 * @return
	 */
	public Parking updateParkingWithStats(Key key, Parking parking){
		parking.setKey(key);
		Datastore.delete(key);
		Datastore.put(parking);
		ParkingForStats parkingForStats = new ParkingForStats(parking, new Date(System.currentTimeMillis()));
		Datastore.put(parkingForStats);
		return parking;
	}
}
<file_sep>/*
-------------------------------
  GLOBAL ERROR CATCH
-------------------------------
*/
(function() {
    var oldErrorHandler = window.onerror;
    if(a.environment.get("debug") === true) {
        window.onerror = function(message, url, line) {
            if(oldErrorHandler) {
                return oldErrorHandler(message, url, line);
            }

            alert("DEBUG MODE, an error occurs\n Message: " + 
                        message + "\n url:" + url + "\n line:" + line);
            return false;
        };
    }
})();


/*
-------------------------------
  CLICK CATCH
-------------------------------
*/

// Bind li click
(function() {
    // Bind element to respond on click to change class
    a.dom.cls('sort-action').tag("a").bind('click', function() {
        var el = a.dom.el(this);
        el.parent().toggleClass('active');
        a.state.forceReloadById("list");
    });
}());

a.dom.id("search").bind("keyup", function() {
    a.storage.memory.setItem("search", this.value);
    a.state.forceReloadById("list");
});

/*
------------------------
  HANDLEBARS.JS
------------------------
*/
Handlebars.registerHelper("toLowerCase", function(object) {
    if(!a.isNull(object) && !a.isString(object.toLowerCase)) {
        return new Handlebars.SafeString(object.toLowerCase());
    } else if(a.isString(object)) {
        return new Handlebars.SafeString(object);
    } else {
        return object;
    }
});
Handlebars.registerHelper("ifCond", function(v1, v2, options) {
    if(v1 === v2) {
        return options.fn(this);
    }
    return options.inverse(this);
});
Handlebars.registerHelper("safeUrl", function(object) {
    if(a.isString(object)) {
        return object.replace(/\\/g, "-").replace(/\//g, "-");
    }
    return object;
});
Handlebars.registerHelper("printDefault", function(object) {
    if(a.isNull(object) || !a.isString(object) || object.length === 0) {
        return new Handlebars.SafeString("--noname--");
    } else {
        return new Handlebars.SafeString(object);
    }
});
Handlebars.registerHelper("booleanToString", function(object) {
    return (object === true) ? "true" : "false";
});
Handlebars.registerHelper("deprecated", function(object) {
    return (object === true) ? "deprecated" : "";
});
Handlebars.registerHelper("unimplemented", function(object) {
    return (object === true) ? "unimplemented" : "";
});

// Produce doc url for given data
Handlebars.registerHelper("produceDoc", function(object) {
    if(a.isString(object) && object.length > 0) {
        // Jersey check
        if(
            object.indexOf("com.sun.jersey") !== -1           ||
            object.indexOf("javax.ws.rs") !== -1              ||
            object.indexOf("org.glassfish.jersey") !== -1     ||
            object.indexOf("com.sun.research.ws.wadl") !== -1
        ) {
            return jerseyDocUrl + object.replace(/\./g, "/") + ".html";
        }

        // Java check
        if(
            object.indexOf("javax") === 0        ||
            object.indexOf("java") === 0         ||
            object.indexOf("org.xml.sax") === 0  ||
            object.indexOf("org.w3c.dom") === 0
        ) {
            return javaDocUrl + object.replace(/\./g, "/") + ".html";
        }

        // Nothing found we try default
        if(a.isString(customDocUrl) && customDocUrl.length > 0) {
            return customDocUrl + object.replace(/\./g, "/") + ".html";
        }
    } else {
        return "";
    }
});



Handlebars.registerHelper("count", function(object) {
    return object.length;
});
Handlebars.registerHelper("debug", function(object) {
    console.log("Current Context");
    console.log("====================");
    console.log(this);

    if(object) {
        console.log("Value");
        console.log("====================");
        console.log(object);
    }
});


/*
------------------------
  APPSTORM.JS
------------------------
*/
(function() {
    a.environment.set("console", "warn");
    a.environment.set("verbose", 1);

    var currentHash = a.page.event.hash.getHash(),
        timerId = null,
        max = 1000;

    // Initialise page event hash system
    a.page.event.hash.setPreviousHash("");
    window.location.href = "#loading_application";

    /**
     * handle "state change" for every browser
    */
    function firstHandle() {
        if(a.page.event.hash.getHash() !== currentHash) {
            window.location.href = "#" + currentHash;
            max = 0;
        }
        if(max-- <= 0) {
            a.timer.remove(timerId);
        }
    };

    // The main starter is here, we will customize it soon
    if(
            currentHash === null
        ||  currentHash === ""
        ||  !a.state.hashExists(currentHash)
    ) {
        currentHash = "list";
    }

    /*
     * Some browser don't get hash change with onHashchange event,
     * so we decide to use timer.
     * Note : a.page.event.hash is more complex, here is little example
    */
    timerId = a.timer.add(firstHandle, null, 10);
})();<file_sep>package com.robocorp2.model.parking;

import java.io.Serializable;
import java.util.UUID;

import javax.xml.bind.annotation.XmlRootElement;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Datastore;
import org.slim3.datastore.Model;

import com.google.appengine.api.datastore.Key;

/**
 * 
 * @author Mathieu
 *
 */
@XmlRootElement
@Model(kind = "Camera")
public class Camera implements Serializable{

	private static final long serialVersionUID = 1L;
	@Attribute(primaryKey = true)
	private Key key;
	@Attribute(lob = true)
	private PointGPS point;
	private double hauteur;
	private int rotationInDegrees;
	private int focal;
	private String adresse;
	
	public Camera(PointGPS point, double hauteur, int rotationInDegrees, int focal, String adresse) {
		super();
		this.key = Datastore.createKey(Camera.class, UUID.randomUUID().toString());
		this.point = point;
		this.hauteur = hauteur;
		this.rotationInDegrees = rotationInDegrees;
		this.focal = focal;
		this.adresse = adresse;
	}
	public Camera() {
		super();
	}
	
	/**
	 * @return the key
	 */
	public Key getKey() {
		return key;
	}
	/**
	 * @param key the key to set
	 */
	public void setKey(Key key) {
		this.key = key;
	}
	/**
	 * @return the point
	 */
	public PointGPS getPoint() {
		return point;
	}
	/**
	 * @param point the point to set
	 */
	public void setPoint(PointGPS point) {
		this.point = point;
	}
	/**
	 * @return the hauteur
	 */
	public double getHauteur() {
		return hauteur;
	}
	/**
	 * @param hauteur the hauteur to set
	 */
	public void setHauteur(double hauteur) {
		this.hauteur = hauteur;
	}
	/**
	 * @return the rotationInDegrees
	 */
	public int getRotationInDegrees() {
		return rotationInDegrees;
	}
	/**
	 * @param rotationInDegrees the rotationInDegrees to set
	 */
	public void setRotationInDegrees(int rotationInDegrees) {
		this.rotationInDegrees = rotationInDegrees;
	}
	/**
	 * @return the focal
	 */
	public int getFocal() {
		return focal;
	}
	/**
	 * @param focal the focal to set
	 */
	public void setFocal(int focal) {
		this.focal = focal;
	}
	/**
	 * @return the adresse
	 */
	public String getAdresse() {
		return adresse;
	}
	/**
	 * @param adresse the adresse to set
	 */
	public void setAdresse(String adresse) {
		this.adresse = adresse;
	}
	
	
}
<file_sep>function DragAndZoom(canvas) {
    function mouseDown(evt) {
        dragStart = evt.point;
    }
    function mouseDrag(evt) {
        var pt = evt.point;
        paper.view.center = new paper.Point(paper.view.center.x - (pt.x - dragStart.x), paper.view.center.y - (pt.y - dragStart.y));
    }
    function mouseUpOut(evt) {
        dragStart = null;
    }
    var dragStart;

    this.populateTool = function (tool) {
        tool.attach('mousedown', mouseDown);
        tool.attach('mousedrag', mouseDrag);
        tool.attach('mouseup', mouseUpOut);
        tool.attach('mouseout', mouseUpOut);
        canvas.addEventListener('DOMMouseScroll', handleScroll);
        canvas.addEventListener('mousewheel', handleScroll);
    }

    var scaleFactor = 1.1;
    var cumulclick = 0;
    var zoom = function (clicks) {
        console.log(clicks);
        cumulclick += clicks/3
        var factor = Math.pow(scaleFactor, cumulclick);
        console.log(cumulclick);
        //paper.view.center = new paper.Point(paper.view.center.x - (pt.x - dragStart.x), paper.view.center.y - (pt.y - dragStart.y));
        console.log(scaleFactor);
        paper.view.zoom = factor;
    };

    var handleScroll = function (evt) {
        console.log("scroll");
        var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
        if (delta)
            zoom(delta);
        return evt.preventDefault() && false;
    };
}
;

function DragAndZoom(canvas) {
    function mouseDown(evt) {
        dragStart = evt.point;
    }
    function mouseDrag(evt) {
        var pt = evt.point;
        paper.view.center = new paper.Point(paper.view.center.x - (pt.x - dragStart.x), paper.view.center.y - (pt.y - dragStart.y));
    }
    function mouseUpOut(evt) {
        dragStart = null;
    }
    var dragStart;

    this.populateTool = function (tool) {
        tool.attach('mousedown', mouseDown);
        tool.attach('mousedrag', mouseDrag);
        tool.attach('mouseup', mouseUpOut);
        tool.attach('mouseout', mouseUpOut);
        canvas.addEventListener('DOMMouseScroll', handleScroll);
        canvas.addEventListener('mousewheel', handleScroll);
    }

    var scaleFactor = 1.1;
    var cumulclick = 0;
    var zoom = function (clicks) {
        console.log(clicks);
        cumulclick += clicks/3
        var factor = Math.pow(scaleFactor, cumulclick);
        console.log(cumulclick);
        //paper.view.center = new paper.Point(paper.view.center.x - (pt.x - dragStart.x), paper.view.center.y - (pt.y - dragStart.y));
        console.log(scaleFactor);
        paper.view.zoom = factor;
    };

    var handleScroll = function (evt) {
        console.log("scroll");
        var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
        if (delta)
            zoom(delta);
        return evt.preventDefault() && false;
    };
}
;<file_sep>jersey-doc-template
===================

Template presentation for [jersey-doc-generator](https://github.com/Deisss/jersey-doc-generator/) output.
It can handle all data elements generated with [jersey-doc-generator](https://github.com/Deisss/jersey-doc-generator/) in a easy and readable
way.

### Screenshot ###

![image](http://www.kirikoo.net/images/14Anonyme-20130819-021044.png)




Installation
------------

The template does work in a pretty simple way. First you need to clone this repository:

    git clone --recursive https://github.com/Deisss/jersey-doc-template

We need to get it in recursive mode, because the template use [AppStorm.JS framework](https://github.com/Deisss/AppStorm.JS)

Now you grab a copy of it, we can make it working!




Usage
-----

First of course, you need to output a file from [jersey-doc-generator](https://github.com/Deisss/jersey-doc-generator/).
In our example (see `data.js`) we locate it to __/resource/data/result.json__.

You need to edit `data.js` file at the root folder:

  * __jerseyDocGenerator__: it's the place to locate the json data returned by [jersey-doc-generator](https://github.com/Deisss/jersey-doc-generator). You can use more than one file...
  * __customDocUrl__: you can specify here your own javadoc, to link classes to your javadoc if they are not java/jersey related.

__javaDocUrl__ and __jerseyDocUrl__ refer to java documentation and jersey documentation.
You probably don't need to change them, as they are pre-configured.

After you did this, it's done, you can use it threw your favorite server, with your favorite browser!




Licence
-------

This project is licensed under MIT licence.
<file_sep>package com.easypark.easypark;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;


import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.places.Places;


public class RecommandationActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recommandation);

        mGoogleApiClient = new GoogleApiClient
                .Builder(this)
                .addApi(Places.GEO_DATA_API)
                .addApi(Places.PLACE_DETECTION_API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }


    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }



    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }
}
<file_sep>package obj;

public class Blob {
	private Point pointHautGauche;
	private Point pointBasDroite;

	public Blob(){
	}
	
	public Blob(int pointHautGaucheX, int pointHautGaucheY, int pointBasDroiteX, int pointBasDroiteY){
		pointHautGauche=new Point(pointHautGaucheX, pointHautGaucheY);
		pointBasDroite=new Point(pointBasDroiteX, pointBasDroiteY);
	}

	public Point getBaricentre() {
		return null;
	}
	public Point getPointHautGauche() {
		return pointHautGauche;
	}
	public void setPointHautGauche(Point pointHautGauche) {
		this.pointHautGauche = pointHautGauche;
	}
	public Point getPointBasDroite() {
		return pointBasDroite;
	}
	public void setPointBasDroite(Point pointBasDroite) {
		this.pointBasDroite = pointBasDroite;
	}
	public String toString(){
		return "X1:"+pointHautGauche.getX()+" Y1:"+pointHautGauche.getY() + " " +"X2:"+pointBasDroite.getX()+" Y2:"+pointBasDroite.getY();	
	}
}
<file_sep>package parking;

/**
 * 
 * @author <NAME>
 * Une place de parking : 
 * - un emplacement dans l'espace
 * - une "rotation" (en bataille, en �pi, en cr�neau)
 * - libre ou non
 *
 */
public class Place {

	private Point point;
	private int rotation;
	private boolean free;
	
	/**
	 * Constructor
	 * @param point
	 * @param rotation
	 * @param free
	 */
	public Place(Point point, int rotation, boolean free) {
		super();
		this.point = point;
		this.rotation = rotation;
		this.free = free;
	}
	
	/**
	 * @return the point
	 */
	public Point getPoint() {
		return point;
	}
	/**
	 * @param point the point to set
	 */
	public void setPoint(Point point) {
		this.point = point;
	}
	/**
	 * @return the rotation
	 */
	public int getRotation() {
		return rotation;
	}
	/**
	 * @param rotation the rotation to set
	 */
	public void setRotation(int rotation) {
		this.rotation = rotation;
	}
	/**
	 * @return the free
	 */
	public boolean isFree() {
		return free;
	}
	/**
	 * @param free the free to set
	 */
	public void setFree(boolean free) {
		this.free = free;
	}
	
	
}
<file_sep>package detectionParking;

import java.util.ArrayList;

import obj.Blob;
import obj.Camera;
import obj.Etage;
import obj.Place;
import obj.Point;
import jni.TraitementJNI;

public class Traitement extends Thread {
	private String idParking;
	private String repertoireImages;
	private Etage etage;
	private Camera camera;
	ArrayList<Place> bufferPlaces=new ArrayList<Place>();
	public Traitement(Camera camera, String idParking, Etage etage, String repertoireImages){
		this.etage = etage;
		this.idParking = idParking;
		this.repertoireImages = repertoireImages;
		this.camera = camera;
	}


	@Override
	public void run() {
		try {
			Thread thread = new Thread(new Runnable() {
				@Override
				public void run() {
					TraitementJNI.getInstance().lancerCapture(camera.getAdresse(),repertoireImages, true);
				}
			});
			thread.start();
			while(true){
				//Vider le buffer si y'a qque chose
				if(!bufferPlaces.isEmpty()){
					for(Place place:bufferPlaces){
						boolean retour = Util.mettreAJourPlace(idParking, etage.getKey(), place);
						if(!retour){
							break;
						}else{
							bufferPlaces.remove(place);
						}
					}
				}
				Blob[] listeBlobs=TraitementJNI.getInstance().getBlobs(camera.getAdresse());
				if(listeBlobs!=null){
					for(Blob pointBlob:listeBlobs){
						//On vérifie si le point correspond à une place visible
						//et on calcule si elle est occupée
						if(pointBlob!=null){
							System.out.println(pointBlob.toString());
							gererOccupation(pointBlob);
						}
					}
				}
				Thread.sleep(40);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void gererOccupation(Blob pointBlob) {
		if(!idParking.equals("0")){
			Camera cam = camera;
			//Pour chaque place on calcule ses coordonnées sur l'image
			//On regarde si elle est dans le champ de vision de la caméra
			//On regarde si un des blobs occupe le repère de la place
			for(Place place:etage.getPlaces()){
				if(isPlaceVisibleParCam(cam, place)){
					if(isPlaceChangeEtat(place, pointBlob)){
						//Si on a perdu la liaision avec le serveur on bufferise
						if(!Util.mettreAJourPlace(idParking, etage.getKey(), place)){
							bufferPlaces.add(place);
						}
					}
				}
			}
		}
	}

	private boolean isPlaceChangeEtat(Place place, Blob pointBlob) {
		boolean placeChangeEtat=false;
		if(place.isFree()){
			if(repereContenuDansBlob(place.getPoint().getX(),place.getPoint().getY(), pointBlob)){
				place.setFree(false);
				placeChangeEtat=true;
			}
		}else{
			//"Loin" est à determiner mais on calcule d'abord si le blob est loin
			//de la place. Si il est loin on n'a rien de plus à calculer
			if(repereContenuDansBlob(place.getPoint().getX(),place.getPoint().getY(), pointBlob)){
				if(place.getBlob()==null){
					//Un blob viens de s'activer sur la place
					//Je le stocke pour pouvoir le comparer au suivant
					place.setBlob(pointBlob);
				}
			}else if(place.getBlob()!=null && distanceEntre2Points(place.getPoint().getX(), pointBlob.getBaricentre().getX(),
					place.getPoint().getY(), pointBlob.getBaricentre().getY())<10){
				//J'avais detecté un blob et il est sorti
				//Du repère de la place
				place.setBlob(null);
				place.setFree(true);
				placeChangeEtat=true;
			}
		}
		return placeChangeEtat;
	}

	private double distanceEntre2Points(double xA, double xB, double yA, double yB) {
		return Math.sqrt(Math.pow(xA-xB, 2)+Math.pow(yA-yB, 2));
	}

	private boolean isPlaceVisibleParCam(Camera cam, Place place) {
		if(idParking.equals("0")){
			// Mode debug avec fichier chargé depuis le disque
			int x, y; //Coordonnées du centre de la place sur l'image
			int ax = 3600;
			int ay = 10500;
			int bz = 12;
			int az = 12000;
			x=ax*(bz/az);
			y=ay*(bz/az);
			System.out.println("x:"+x+" y:"+y);
			return true;
		}else{
			int x, y; //Coordonnées du centre de la place sur l'image
			int ax = Math.abs((int) (cam.getPoint().getX()-place.getPoint().getX()));
			int ay = Math.abs((int) (cam.getPoint().getY()-place.getPoint().getY()));
			int bz = cam.getFocal();
			int az = (int) (Math.sqrt((Math.pow(cam.getHauteur(),2)+Math.pow(ay,2))));
			x=ax*(bz/az);
			y=ay*(bz/az);

			//Place visible sur 28 cm de large et à partir de 15 cm de haut par rapport
			//à l'image sur une feuille
			//A calibrer par caméra
			if((x<1 || x>280)||(y<1 || y>15)){
				return false;
			}else{
				place.setPointLocal(new Point(x, y));
				return true;
			}
		}
	}
	public boolean repereContenuDansBlob(double x, double y, Blob blob){
		//Le blob est contenu dans un rectangle toujours horizontal
		//Du coup la règle est simple pour savoir si un point est inclus dans
		//le périmètre d'un Rectangle

		//X compris entre le X du point haut gauche et le X du point bas droite
		//Y compris entre le Y du point haut gauche et le Y du point bas droite
		return (x>=blob.getPointHautGauche().getX() && x<=blob.getPointBasDroite().getX()) &&
				(y>=blob.getPointBasDroite().getY() && y<=blob.getPointHautGauche().getY());
	}
}
<file_sep>package com.robocorp2.model.parking;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Datastore;
import org.slim3.datastore.Model;

import com.google.appengine.api.datastore.Key;
import com.robocorp2.core.PlaceStatus;
import com.robocorp2.core.PlaceType;

/**
 * 
 * @author <NAME>
 * Une place de parking : 
 * - un emplacement dans l'espace
 * - une "rotation" (en bataille, en épi, en créneau)
 * - libre ou non
 *
 */
@XmlRootElement
@Model(kind = "Place")
public class Place implements Serializable{

	private static final long serialVersionUID = 1L;
	@Attribute(primaryKey = true)
	private Key key;
	private int numeroDePlace;
	@Attribute(lob = true)
	private PointGPS point;
	private int rotation;
	private PlaceStatus status;
	private PlaceType type;
	
	public Place(){
		
	}
	/**
	 * Constructor
	 * @param point
	 * @param rotation
	 * @param free
	 */
	public Place(PointGPS point, int numero, int rotation, PlaceStatus status, PlaceType type) {
		super();
		this.key = Datastore.createKey(Place.class, numero);
		this.point = point;
		this.numeroDePlace = numero;
		this.rotation = rotation;
		this.status = status;
		this.type = type;
	}
	
	
	/**
	 * @return the key
	 */
	public Key getKey() {
		return key;
	}
	/**
	 * @param key the key to set
	 */
	public void setKey(Key key) {
		this.key = key;
	}
	/**
	 * @return the point
	 */
	public PointGPS getPoint() {
		return point;
	}
	/**
	 * @param point the point to set
	 */
	public void setPoint(PointGPS point) {
		this.point = point;
	}
	/**
	 * @return the rotation
	 */
	public int getRotation() {
		return rotation;
	}
	/**
	 * @param rotation the rotation to set
	 */
	public void setRotation(int rotation) {
		this.rotation = rotation;
	}
	
	
	/**
	 * @return the status
	 */
	public PlaceStatus getStatus() {
		return status;
	}
	/**
	 * @param status the status to set
	 */
	public void setStatus(PlaceStatus status) {
		this.status = status;
	}
	
	public boolean isFree(){
		if(this.status.equals(PlaceStatus.FREE)){
			return true;
		}
		return false;
	}
	/**
	 * @return the numeroDePlace
	 */
	public int getNumeroDePlace() {
		return numeroDePlace;
	}
	/**
	 * @param numeroDePlace the numeroDePlace to set
	 */
	public void setNumeroDePlace(int numeroDePlace) {
		this.numeroDePlace = numeroDePlace;
	}
	/**
	 * @return the type
	 */
	public PlaceType getType() {
		return type;
	}
	/**
	 * @param type the type to set
	 */
	public void setType(PlaceType type) {
		this.type = type;
	}
	
	
}
<file_sep><div class="span3 columns" id="rest-detail">
	<h1>Details</h1>
	<div id="rest-content">
		<h5>Click on any API item to see details</h5>
	</div>
</div>
<div class="span9 columns" id="rest-global">
	{{#content}}
		<div onclick="loadDetail('{{type}}', '{{path}}');" class="api-line {{toLowerCase type}} {{deprecated deprecated}} {{unimplemented unimplemented}}">
			<div>
				<span>{{type}}</span>
				{{path}}
				<a href="{{produceDoc output}}" target="_blank">{{output}}</a>
			</div>
		</div>
	{{/content}}
	{{^content}}
		<div class="api-line get text-center">
			No match found
		</div>
	{{/content}}
</div>

<file_sep># robocorp2-CarPark
Projet Robocorp2 : CarPark
<file_sep>package obj;

public class Point {
	private int x;
	private int y;
	public Point(int pointX, int pointY) {
		x=pointX;
		y=pointY;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}
<file_sep>/**
 * Convert the system type before rendering
 *
 * @param data {String} The data to replace
*/
function convertType(data) {
    if(a.isString(data)) {
        return data.replace("javax.ws.rs.", "");
    } else {
        return data;
    }
};


/**
 * Sort between 2 string
 *
 * @param a {String} The first string
 * @param b {String} The second string
*/
function __sortString(a,b) {
    if(a < b) {
        return -1;
    } else if(a > b) {
        return 1;
    }
    return 0;
};


/**
 * Sort elements by type (HTTP Verb)
 *
 * @param data {Array} The array to sort
*/
function sortByType(data) {
    if(a.isArray(data)) {
        return data.sort(function(a,b) {
            var typeA = a.type.toLowerCase(),
                typeB = b.type.toLowerCase();

            // Change delete string to appear on bottom (place "z" at beginning)
            if(typeA === "delete") {    typeA = "zdelete";  }
            if(typeB === "delete") {    typeB = "zdelete";  }

            // Same with head and options (place at first)
            if(typeA === "head") {  typeA = "zhead";    }
            if(typeB === "head") {  typeB = "zhead";    }
            if(typeA === "options") {   typeA = "zoptions"; }
            if(typeB === "options") {   typeB = "zoptions"; }

            return __sortString(typeA, typeB);
        });
    }
    return data;
};

/**
 * Sort elements by path (HTTP Path)
 *
 * @param data {Array} The array to sort
*/
function sortByPath(data) {
    if(a.isArray(data)) {
        return data.sort(function(a,b) {
            var typeA = a.path.toLowerCase(),
                typeB = b.path.toLowerCase();

            return __sortString(typeA, typeB);
        });
    }
    return data;
};

/**
 * Sort elements by output (HTTP Return)
 *
 * @param data {Array} The array to sort
*/
function sortByOutput(data) {
    if(a.isArray(data)) {
        return data.sort(function(a,b) {
            var typeA = a.output.toLowerCase(),
                typeB = b.output.toLowerCase();

            return __sortString(typeA, typeB);
        });
    }
    return data;
};<file_sep>package com.robocorp2.API;


import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.slim3.datastore.Datastore;

import com.google.appengine.api.datastore.Key;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.robocorp2.DAO.ParkingDAO;
import com.robocorp2.core.KeyAdapterSerializer;
import com.robocorp2.model.parking.Etage;
import com.robocorp2.model.parking.Parking;
import com.robocorp2.model.parking.Place;
import com.robocorp2.model.parking.PointGPS;
import com.simplapi.jersey.doc.annotation.ApiAuthor;
import com.simplapi.jersey.doc.annotation.ApiDoc;
import com.simplapi.jersey.doc.annotation.ApiVersion;

@Path("parking")
@ApiDoc("Gestion du parking lui même : création, récupération du schéma, récupération d'une place...")
@ApiAuthor("<NAME>")
@ApiVersion("0.1")
public class ParkingAPI {
	public static Gson gson = (new GsonBuilder()).serializeNulls()
			.setPrettyPrinting().registerTypeAdapter(Key.class, new KeyAdapterSerializer()).create();
	@PUT
	@Path("create")
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@ApiDoc("Créé un nouveau parking et lui attribue une clé qui est retournée")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	public String createParking(Parking parking){
		Key key = ParkingDAO.getInstance().saveParking(parking);
		return Datastore.keyToString(key);
	}
	
	@POST
	@Path("edit/{key}")
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@ApiDoc("Edite le modèle de parking, pour ajouter/enlever des places. Retourne le parking modifié")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	public String editParking(@PathParam("key") String key, Parking parking){
		Key nativeKey = Datastore.stringToKey(key);
		return gson.toJson(ParkingDAO.getInstance().editParking(nativeKey, parking));
	}
	
	@GET
	@Path("get/{key}")
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@ApiDoc("Récupère un modèle de parking avec sa clé")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	public String getParkingByKey(@PathParam("key") String key){
		Parking parking = ParkingDAO.getInstance().getParkingByKey(Datastore.stringToKey(key));
		return gson.toJson(parking);
	}
	
	@GET
	@Path("get/{latitude}/{longitude}")
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@ApiDoc("Récupère un modèle de parking avec sa coordonnée GPS")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	public String getParkingByGPSPoint(@PathParam("latitude") double latitude, @PathParam("longitude") double longitude){
		return gson.toJson(ParkingDAO.getInstance().getParkingByPointGPS(new PointGPS(latitude, longitude)));
	}
	
	@GET
	@Path("search/{latitude}/{longitude}")
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	@ApiDoc("Recherche une liste de parkings les plus proches (max 5) avec une coordonnée GPS")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	public String searchParkingByGPSPoint(@PathParam("latitude") double latitude, @PathParam("longitude") double longitude){
		return gson.toJson(ParkingDAO.getInstance().searchParkingsByPointGPS(new PointGPS(latitude, longitude)));
	}
	
	@GET
	@Path("getNumberOfFreePlaces/{idParking}")
	@Consumes("Application/JSON")
	@Produces("Application/JSON")
	@ApiDoc("Donne le nombre de places libres dans un parking")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	public String getNumberFreePlaces(@PathParam("idParking") String keyParking){
		int nbFreePlaces = 0;
		Parking parking = ParkingDAO.getInstance().getParkingByKey(Datastore.stringToKey(keyParking));
		for(Etage etage : parking.getEtages()){
			for(Place place : etage.getPlaces()){
				if(place.isFree()){
					nbFreePlaces++;
				}
			}
		}
		return nbFreePlaces+"";
	}
}
<file_sep>#include <stdio.h>
#include <iostream>

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <math.h>
#include <jni_TraitementJNI.h>
#include <jni.h>
#include <windows.h>

using namespace cv;
using namespace std;

class Blob{
public:
	Point pointBasDroite, pointHautGauche;
};
//
std::map<String,vector<Blob> > blobList;
int traitementCamera(String adresseCamera, bool debug, String repertoireImages){
	//global variables
	Mat frame; //current frame
	Mat resize_blur_Img;
	Mat foreground; //Image du premier plan
	Mat binaryImg;
	//Mat TestImg;
	Mat ContourImg; //fg mask fg mask generated by MOG2 method
	cv::Ptr<BackgroundSubtractor> mOG2 = createBackgroundSubtractorMOG2(300,32,false);

	//Capture d'un fichier pour les tests,
	//d'une webcam pour la mise en prod
	VideoCapture stream1;
	if(isdigit(adresseCamera.c_str()[0])){
		stream1=VideoCapture(atoi(adresseCamera.c_str()));
	}else{
		stream1=VideoCapture(adresseCamera);
	}

	//Pour nettoyer les pixels isolés faux positif
	Mat element = getStructuringElement(MORPH_RECT, Size(7, 7), Point(3,3) );
	if(blobList.find(adresseCamera)->first==NULL){
		blobList.insert(std::pair<String,vector<Blob> >(adresseCamera,vector<Blob>()));
	}
	int i=1;
	std::map<String, vector<Blob> >::iterator listeBlob=blobList.find(adresseCamera);
	while (true) {
		listeBlob->second.clear();
		if((stream1.read(frame))){ //get one frame form video
			//Resize
			//Reduire l'image peut accelerer le traitement
			resize(frame, resize_blur_Img, Size(frame.size().width/1, frame.size().height/1) );
			//Leger flou pour éliminer des détails qui feraient de faux positifs
			blur(resize_blur_Img, resize_blur_Img, Size(4,4) );
			//Background subtraction
			mOG2->apply(resize_blur_Img, foreground, -1);//,-0.5);

			// Suppression des points isolés
			morphologyEx(foreground, binaryImg, CV_MOP_CLOSE, element);

			//Suppression de l'ombre
			//Sur le foreground l'ombre est grise alors que l'objet lui même est blanc
			threshold(binaryImg, binaryImg, 128, 255, CV_THRESH_BINARY);

			//On essaye de strucuturer les objets trouvés par contours
			vector<vector<Point> > contours;
			findContours(binaryImg,
					contours, // a vector of contours
					CV_RETR_EXTERNAL, // retrieve the external contours
					CV_CHAIN_APPROX_NONE); // all pixels of each contours
			vector<vector<Point> > contours_poly( contours.size() );
			vector<Rect> boundRect( contours.size() );
			vector<Point2f>center( contours.size() );
			vector<float>radius( contours.size() );

			for( unsigned int index = 0; index < contours.size(); index++ )
			{
				approxPolyDP( Mat(contours[index]), contours_poly[index], 3, true );
			}

			if(contours_poly.size()<200){
				for( unsigned int j = 0; j < contours_poly.size(); j++ )
				{
					if(contourArea(contours_poly[j])>400){
						boundRect[j] = boundingRect( Mat(contours_poly[j]) );
						Blob blob = Blob();
						blob.pointBasDroite=boundRect[j].br();
						blob.pointHautGauche=boundRect[j].tl();
						listeBlob->second.push_back(blob);
						//						printf("Traitement X1:%i Y1:%i X2:%i Y2:%i\n",blob.pointHautGauche.x, blob.pointHautGauche.y, blob.pointBasDroite.x, blob.pointBasDroite.y);
						if(debug && ((i%25)==0)){
							Scalar color = Scalar(0, 0, 255);
							rectangle( frame, boundRect[j].tl(), boundRect[j].br(), color, 2, 8, 0 );
							std::stringstream nomFichierSortie1;
							std::stringstream nomFichierSortie2;
							nomFichierSortie1 << repertoireImages<<"/foreground/image_" << i << ".jpg";
							imwrite(nomFichierSortie1.str(), foreground);
							nomFichierSortie2 << repertoireImages<<"/image_" << i << ".jpg";
							imwrite(nomFichierSortie2.str(), frame);
						}
					}
				}
			}
			Sleep(40);
		}
		i++;
	}
	return true;
}
JNIEXPORT void JNICALL Java_jni_TraitementJNI_lancerCapture
(JNIEnv *env, jobject object, jstring name, jstring repertoireImages, jboolean debug){
	const char *str= env->GetStringUTFChars(name,0);
	const char *repertoire= env->GetStringUTFChars(repertoireImages,0);

	printf("Mode debug :%s\n", debug ? "true" : "false");
	printf("Nom du fichier: %s\n", str);
	traitementCamera(str, debug, repertoire);
	//need to release this string when done with it in order to
	//avoid memory leak
	env->ReleaseStringUTFChars(name, str);
}
JNIEXPORT jobjectArray JNICALL Java_jni_TraitementJNI_getBlobs
(JNIEnv *env, jobject object, jstring adresseCamera){
	jobjectArray result;
	const char *str= env->GetStringUTFChars(adresseCamera,0);
	env->ReleaseStringUTFChars(adresseCamera, str);
	std::map<String, vector<Blob> >::iterator iteratorBlob=blobList.find(str);
	vector<Blob> listeBlob = iteratorBlob->second;
	jclass cls;
	cls = env->FindClass("obj/Blob");
	if(cls==NULL){
		printf("classe NULL");
	}
	result=env->NewObjectArray(listeBlob.size(),cls,NULL);
	for(unsigned int i=0;i<listeBlob.size();i++){
		jmethodID constructor;
		jint args[4];
		jobject object;
		constructor = env->GetMethodID(cls, "<init>", "(IIII)V");
		Blob blob = listeBlob[i];
		args[0] = blob.pointHautGauche.x;
		args[1] = blob.pointHautGauche.y;
		args[2] = blob.pointBasDroite.x;
		args[3] = blob.pointBasDroite.y;
//		printf("DLL blob X1:%i Y1:%i X2:%i Y2:%i\n",blob.pointHautGauche.x, blob.pointHautGauche.y, blob.pointBasDroite.x, blob.pointBasDroite.y);
//		printf("DLL ARGS X1:%i Y1:%i X2:%i Y2:%i\n",args[0], args[1], args[2], args[3]);
		object = env->NewObject(cls, constructor, args[0], args[1], args[2], args[3]);
		env->SetObjectArrayElement(result, i, object);
		return result;
	}
}
<file_sep>// Root controller system, loading main app system here
(function() {
	/**
	 * Generate function to replace an id by the content given
	 *
	 * @param id {String} The id to perform changes
	*/
	function __replaceById(id) {
		return function(content) {
			a.page.template.replace(document.getElementById(id), content);
		}
	};



	// Preload url
	a.page.template.get("resource/html/list.html");
	a.page.template.get("resource/html/test.html");
	a.page.template.get("resource/html/detail.html");


	// Handle the logged part (when user sign in successfully)
	var content = {
		bootOnLoad : true,
		id   : "root",
		data : {},
		converter : function(data) {
			a.storage.memory.setItem("api", data);
		},
		children : [
			{
				id : "list",
				hash : "list",
				title: "Documentation - list",
				load : __replaceById("page-content"),
				data : {
					api : "{{memory: api}}"
				},
				include : {
					html : "resource/html/list.html"
				},
				converter : function(data) {
					// Rendering
					var arr = [];
					for(var i in data.api) {
						var tmp = jerseyDocPrettify(data.api[i]);
						arr = arr.concat(tmp);
					}
					// Sorting final result
					data.content = a.clone(arr);

					if(a.dom.id("sort-by-output").hasClass("active")) {
						data.content = sortByOutput(data.content);
					}
					if(a.dom.id("sort-by-path").hasClass("active")) {
						data.content = sortByPath(data.content);
					}
					if(a.dom.id("sort-by-type").hasClass("active")) {
						data.content = sortByType(data.content);
					}

					// Filtering deprecated & unimplemented & search
					var deprecated    = !a.dom.id("include-type-deprecated")
														.hasClass("active"),
						unimplemented = !a.dom.id("include-type-unimplemented")
														.hasClass("active"),
						boolSearch    = false;
						search        = a.storage.memory.getItem("search");

					if(a.isString(search) && search.length > 0) {
						boolSearch = true;
						search = search.toLowerCase();
					}

					var i = data.content.length;
					while(i--) {
						var el = data.content[i];
						// Deprecated && unimplemented
						if(
							(deprecated    && el.deprecated === true)    ||
							(unimplemented && el.unimplemented === true)
						) {
							data.content.splice(i, 1);
							continue;
						}
						// Search
						if(boolSearch) {
							if(
								el.path.toLowerCase().search(search) === -1 &&
								el.type.toLowerCase().search(search) === -1 &&
								el.output.toLowerCase().search(search) === -1
							) {
								data.content.splice(i, 1);
								continue;
							}
						}
					}

					// Store parsed content
					a.storage.memory.setItem("content", data.content);
				},
				preLoad : function(result) {
					a.dom.id('menu-test').css('display', 'none');
					a.dom.id('menu-list').css('display', 'block');
					a.storage.memory.setItem("gotry", true);
					result.done();
				}
			},
			{
				// TODO : currently switching from list to test is not well done, as root lost html elements doing this ! we should avoid test here so ! Correct that, and make a better version of this !
				id   : "test",
				hash : "test/{{type: [a-zA-Z]+}}/{{path : .+}}",
				title: "Documentation - test request",
				load : __replaceById("page-content"),
				data : {
					type : "{{type}}",
					path : "{{path}}",
					api  : "{{memory : api}}"
				},
				include : {
					html : "resource/html/test.html"
				},
				converter : function(data) {
					// Rendering
					var arr = [];
					for(var i in data.api) {
						var tmp = jerseyDocPrettify(data.api[i]);
						arr = arr.concat(tmp);
					}

					data.content = null;
					for(var i=0, l=arr.length; i<l; ++i) {
						var el = arr[i];
						// See Handlebars - safe url function in boot.js
						var tmp = el.path.replace(/\\/g, "-").replace(/\//g, "-");
						if(tmp == data.path && el.type == data.type) {
							data.content = el;
							break;
						}
					}

					// If we found some data, now we proceed input list to find relation
					// between url, and inputList
					if(data.content) {
					
					}
				},
				preLoad : function(result) {
					a.dom.id('menu-list').css('display', 'none');
					a.dom.id('menu-test').css('display', 'block');
					result.done();
				},
				postLoad : function(result) {
					// Store parsed content
					a.storage.memory.setItem("current", result.getData("content"));
					a.storage.memory.setItem("gotry", false);

					// Loading left state
					a.state.loadById("detail");
					result.done();
				}
			}
		]
	};

	var detail = {
		id : "detail",
		load : __replaceById("rest-content"),
		data : {
			api   : "{{memory: current}}",
			gotry : "{{memory: gotry}}"
		},
		include : {
			html : "resource/html/detail.html"
		}
	};

	// Populate tree data
	for(var i=0, l=jerseyDocGenerator.length; i<l; ++i) {
		content.data[i] = jerseyDocGenerator[i];
	}

	// Finally we add elements to system
	a.state.add(content);
	a.state.add(detail);
})();


/**
 * Load a specific detail list
 *
 * @param type {String} The type to search
 * @param path {String} The path to search
*/
function loadDetail(type, path) {
	var data = a.storage.memory.getItem("content");
	var i = data.length;
	while(i--) {
		if(data[i].type === type && data[i].path === path) {
			a.storage.memory.setItem("current", data[i]);
			a.state.loadById("detail");
			break;
		}
	}
};

/**
 * Request to active a different tab from the default one
 *
 * @param current {String} The tab name to activate
*/
function changeTestTab(current) {
	var opposite = (current === 'response') ? 'request' : 'response';

	a.dom.id('content-' + current  + ', menu-' + current ).addClass('active');
	a.dom.id('content-' + opposite + ', menu-' + opposite).removeClass('active');
};

/**
 * get the "raw" header add, and append it to dom
*/
function addTestHeader() {
	a.page.template.get("tmpl_test_header", null, function(content) {
		a.page.template.append(
			document.getElementById("additional-header"),
			content
		);

		// We create a new "additional-header" if needed
		var id = "additional-header";
		var span = a.dom.id(id).cls("span6").getElements();
		if(span.length >= 2) {
			var container = document.createElement("div");
			container.className = "container-fluid";

			var row = document.createElement("div");
			row.className = "row-fluid";
			row.id = id;

			container.appendChild(row);

			// We get id, remove it, and create to parent a new element with
			// this id, to always have no trouble with row-fluid system
			a.dom.id(id).attribute("id", null).parent().parent().append(container);
		}
	});
};

function addTestQueryParam() {
	a.page.template.get("tmpl_test_parameter", null, function(content) {
		a.page.template.append(
			document.getElementById("additional-query-parameter"),
			content
		);

		// We create a new "additional-header" if needed
		var id = "additional-query-parameter";
		var span = a.dom.id(id).cls("span12").getElements();
		if(span.length >= 1) {
			var container = document.createElement("div");
			container.className = "container-fluid";

			var row = document.createElement("div");
			row.className = "row-fluid";
			row.id = id;

			container.appendChild(row);

			// We get id, remove it, and create to parent a new element with
			// this id, to always have no trouble with row-fluid system
			a.dom.id(id).attribute("id", null).parent().parent().append(container);
		}
	});
};


/**
 * Perform a test on given parameters
*/
function testRequest() {
	var dom  = document.getElementById("test-request"),
		form = a.form.get(dom);

	var notParsedUrl = form["url-server"];
	// Remove last char if it's not well positioned
	if(notParsedUrl.substr(notParsedUrl.length - 1) == "/") {
		notParsedUrl = notParsedUrl.substr(0, notParsedUrl.length - 1);
	}
	// Add "http"
	if(notParsedUrl.substr(0, 7) != "http://") {
		notParsedUrl = "http://" + notParsedUrl;
	}
	notParsedUrl += form["content-path"];

	// Now the url is in "final" mode, we can bind param to it
	// To do so, we will use parsing from Appstorm, as it is ready for that !
	var preparedUrl = notParsedUrl.replace(/\{/, "{{").replace(/\}/, "}}");

	// TODO: the good things is that URL is close to be OK for appstorm too from state... deal with it
	var parsedUrl = preparedUrl;

	// Manage extra parameter data
	var parameterKeyList   = a.dom.cls("parameter-key").getElements(),
		parameterValueList = a.dom.cls("parameter-value").getElements();

	var parameterResult = [];
	for(var i=0, l=parameterKeyList.length; i<l; ++i) {
		var key = parameterKeyList[i].value,
			val = parameterValueList[i].value;

		if(!a.isNull(key) && a.isString(key) && key.length > 0) {
			parameterResult.push(
				  encodeURIComponent(key)
				+ "="
				+ encodeURIComponent(val)
			);
		}
	}

	// User gives some custom parameters
	if(parameterResult.length > 0) {
		parsedUrl += "?" + parameterResult.join("&");
	}

	// Building basic Ajax request options
	var options = {
		url:     parsedUrl,
		type:    "raw",
		method:  form["content-method"],
		cache:   false,
		data:    form["text-request-body"] || "",
		header:  {}
	};

	if(form["accept"]) {
		options.header["accept"] = form["accept"];
	}
	if(form["content-type"]) {
		options.header["content-type"] = form["content-type"];
		// Set in JSON mode
		if(form["content-type"].toLowerCase() === "application/json") {
			options.type = "json";
		} else if(form["content-type"].toLowerCase() === "application/xml") {
			options.type = "xml";
		}
	}
	if(form["basic-auth"]) {
		options.header["authorization"] = "Basic " + Base64.encode(form["basic-auth"]);
	}

	// We grab custom data from user
	var headerKeyList      = a.dom.cls("header-key").getElements(),
		headerValueList    = a.dom.cls("header-value").getElements();

	for(var i=0, l=headerKeyList.length; i<l; ++i) {
		var key = headerKeyList[i].value || "",
			val = headerValueList[i].value || "";

		if(
			!a.isNull(key) && a.isString(key) && key.length > 0
			&& !a.isNull(val)
		) {
			options.header[key] = val;
		}
	}


	// Preparing request for sending
	var request = new a.ajax(options,
		// success function
		function(result, statusCode) {
			// we can retrieve all header data from request
			var body   = document.getElementById("text-response-body"),
				status = document.getElementById("text-response-status"),
				header = document.getElementById("text-response-header");

			// Erase
			body.innerHTML   = "";
			header.innerHTML = "";

			// HTTP Status code
			status.value = statusCode;

			// Put header
			header.innerHTML += request.request.getAllResponseHeaders().toString();

			// Body response
			body.innerHTML   += result;

			// Show results
			changeTestTab("response");

		// error function
		}, function(statusCode) {
			// we can retrieve all header data from request
			var body   = document.getElementById("text-response-body"),
				status = document.getElementById("text-response-status"),
				header = document.getElementById("text-response-header");

			// Erase
			body.innerHTML   = "";
			header.innerHTML = "";

			// HTTP Status code
			status.value = statusCode;

			// Put header
			header.innerHTML += request.request.getAllResponseHeaders().toString();

			// Show results
			changeTestTab("response");
		});

	// Starting request
	request.send();
};<file_sep># Serveur static de test
## Installation

sudo npm install -g connect serve-static

<file_sep>package obj;

import detectionParking.JsonIgnoreProperties;

public class Camera {
	private String key;
	private PointGPS point;
	private double hauteur;
	private int rotationInDegrees;
	private int focal;
	private String adresse;
	@JsonIgnoreProperties({"key"})

	public PointGPS getPoint() {
		return point;
	}
	public void setPoint(PointGPS point) {
		this.point = point;
	}
	public double getHauteur() {
		return hauteur;
	}
	public void setHauteur(double hauteur) {
		this.hauteur = hauteur;
	}
	public int getRotationInDegrees() {
		return rotationInDegrees;
	}
	public void setRotationInDegrees(int rotationInDegrees) {
		this.rotationInDegrees = rotationInDegrees;
	}
	public int getFocal() {
		return focal;
	}
	public void setFocal(int focal) {
		this.focal = focal;
	}
	public String getAdresse() {
		return adresse;
	}
	public void setAdresse(String adresse) {
		this.adresse = adresse;
	}
}
<file_sep>package com.roboborp2.API;

import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.Test;
import org.slim3.datastore.Datastore;

import com.robocorp2.API.ParkingAPI;
import com.robocorp2.DAO.ParkingDAO;
import com.robocorp2.model.parking.Camera;
import com.robocorp2.model.parking.Etage;
import com.robocorp2.model.parking.Parking;
import com.robocorp2.model.parking.Place;
import com.robocorp2.model.parking.PointGPS;
import com.robocorp2.model.parking.Vecteur;

public class ParkingTestAPI {

	@Test
	public void testCreate(){
		String nom = "Parking de démo";
		String adresse = "Adresse - 31000 Toulouse";
		ArrayList<Etage> etages = new ArrayList<Etage>();
		ArrayList<Place> places = new ArrayList<Place>();
		ArrayList<Vecteur> chemins = new ArrayList<Vecteur>();
		ArrayList<Camera> cameras = new ArrayList<Camera>(); 
		
		places.add(new Place(new PointGPS(1.0, 2.0), 1, 90, true));
		places.add(new Place(new PointGPS(2.0, 3.0), 2, 90, true));
		
		chemins.add(new Vecteur(new PointGPS(2.0, 4.0), new PointGPS(4.0, 7.0)));
		chemins.add(new Vecteur(new PointGPS(4.0, 7.0), new PointGPS(9.0, 8.0)));
		
		cameras.add(new Camera(new PointGPS(1.0,1.0), 4, 90, 120));
		etages.add(new Etage(places, chemins, cameras));
		
		
		Parking parking = new Parking(null, etages, nom, adresse);
		
		String parkingKey = new ParkingAPI().createParking(parking);
		
		Parking parkingFromStore = ParkingDAO.getInstance().getParkingByKey(Datastore.stringToKey(parkingKey));
		
		assertEquals(parkingFromStore, parking);
		
		Datastore.delete(Datastore.stringToKey(parkingKey));
	}
	
	@Test
	public void testEdit(){
		
	}
}
<file_sep>var connect = require('connect');
var serveStatic = require('serve-static');
// Server de test contenant le template
connect().use(serveStatic(__dirname + '/bower_components/admin-lte')).listen(1235);
connect().use(serveStatic(__dirname)).listen(1234);
<file_sep>package com.robocorp2.API;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

import org.slim3.datastore.Datastore;

import com.google.appengine.api.datastore.Key;
import com.robocorp2.DAO.ParkingDAO;
import com.robocorp2.core.dijkstra.Dijkstra;
import com.robocorp2.core.dijkstra.Arc;
import com.robocorp2.core.dijkstra.Graphe;
import com.robocorp2.core.dijkstra.Sommet;
import com.robocorp2.model.parking.Etage;
import com.robocorp2.model.parking.Parking;
import com.robocorp2.model.parking.Place;
import com.robocorp2.model.parking.PointGPS;
import com.robocorp2.model.parking.Vecteur;
import com.simplapi.jersey.doc.annotation.ApiAuthor;
import com.simplapi.jersey.doc.annotation.ApiDoc;
import com.simplapi.jersey.doc.annotation.ApiUnimplemented;
import com.simplapi.jersey.doc.annotation.ApiVersion;

@Path("chemin")
@ApiDoc("Calcul et retour des chemins pour accéder à une place")
@ApiAuthor("<NAME>")
@ApiVersion("0.1")
public class CheminAPI {

	@GET
	@Path("getRoute/{idParking}/{idPlace}")
	@ApiDoc("Donne le chemin jusqu'à une place")
	@ApiAuthor("<NAME>")
	@ApiVersion("0.1")
	@ApiUnimplemented(value = "not implemented")
	public PointGPS[] getCheminToPlace(@PathParam("idParking") String parkingKey, @PathParam("idPlace") int idPlace){
		Key nativeKey = Datastore.stringToKey(parkingKey);
		Parking parking = ParkingDAO.getInstance().getParkingByKey(nativeKey);

		Place placeToGo = null;
		Etage etageToGo = null;
		for(Etage etage : parking.getEtages()){
			for(Place place : etage.getPlaces()){
				if(place.getNumeroDePlace() == idPlace){
					placeToGo = place;
					etageToGo = etage;
				}
			}
		}

		ArrayList<Vecteur> chemin = new ArrayList<Vecteur>();
		PointGPS pointToGo = placeToGo.getPoint();

		// calcul d'un chemin

		// 1 on calcule le graphe de l'étage


		List<Sommet> nodes = new ArrayList<Sommet>();
		List<Arc> edges = new ArrayList<Arc>();


		for(Vecteur vecteur : etageToGo.getChemins()){
			PointGPS debut = vecteur.getPointDebut();
			PointGPS fin = vecteur.getPointFin();

			boolean addDebut = true;
			boolean addFin = true;
			for(Sommet node : nodes){
				if(node.getPointGPS().equals(debut)){
					addDebut = false;
				}
				if(node.getPointGPS().equals(fin)){
					addFin = false;
				}
			}
			if(addDebut){
				nodes.add(new Sommet(Datastore.keyToString(vecteur.getKey()), debut));
			}
			if(addFin){
				nodes.add(new Sommet(Datastore.keyToString(vecteur.getKey()), fin));
			}
		}

		for(Vecteur vecteur : etageToGo.getChemins()){
			double norme = vecteur.getNorme();

			Sommet source = null;
			Sommet destination = null;
			for(Sommet node : nodes){
				if(node.getPointGPS().equals(vecteur.getPointDebut())){
					source = node;
				}
				if(node.getPointGPS().equals(vecteur.getPointFin())){
					destination = node;
				}
			}

			edges.add(new Arc(Datastore.keyToString(vecteur.getKey()), source, destination, norme));

		}

		Graphe graph = new Graphe(nodes, edges);
		Dijkstra dijkstra = new Dijkstra(graph);

		// find the nodes

		PointGPS debut = new PointGPS(parking.getPointGPSLat(), parking.getPointGPSLon());
		PointGPS destination = placeToGo.getPoint();

		Sommet vertexDebut = null;
		Sommet vertexFin = null;
		for(Sommet node : nodes){
			if(node.getPointGPS().equals(debut)){
				vertexDebut = node;
			}
			if(node.getPointGPS().equals(destination)){
				vertexFin = node;
			}
		}

		dijkstra.execute(vertexDebut);
		LinkedList<Sommet> path = dijkstra.getPath(vertexFin);

		PointGPS[] itineraire = new PointGPS[path.size()];
		int i = 0;
		for(Sommet vertex : path){
			itineraire[i] = vertex.getPointGPS();
			i++;
		}

		return itineraire; 

	}
}
<file_sep>/**
 * Default templating object, used internally
 * NOTE: must be cloned (using a.clone) before any use
*/
var jerseyDocObject = {
    // The final path (concat of every sub path)
    path: "",

    // Merge all consumes/produces found to extract list of available one
    consumeList: [],
    produceList: [],

    // General documentation (overriden by latest everytimes exect docList and nameList)
    author: "",
    version: "",
    docList: [],
    nameList: [],

    // One resource/subresource declare this, the full sub-line(s) get this state
    deprecated: false,
    unimplemented: false,

    // Final ending (method content)
    inputList: [],
    output: "",
    // GET, POST, PUT, DELETE, ...
    type: "GET"
};

/**
 * Main prettify class
*/
var jerseyDocPrettify = (function() {
    "use strict";

    /**
     * Detect a class type
     *
     * @param data {Mixed} The data to check
    */
    function __detectClass(data) {
        return (!a.isNull(data) && !a.isNull(data.methodList));
    };

    /**
     * Check is a string is valid (and contains data) or not
     *
     * @param data {Mixed}
     * @return {Boolean} True or false, if it's a valid with data string or not
    */
    function __validString(data) {
        return (a.isString(data) && data.length > 0);
    };

    /**
     * From two part of path, create a single concat version
     *
     * @param path1 {String} The first path to concat
     * @param path2 {String} The second path to concat
     * @return {String} The concat version
    */
    function __concatPath(path1, path2) {
        if(path1.charAt(path1.length - 1) != "/") {
            path1 += "/";
        }

        if(__validString(path2)) {
            // Sanitize url (remove all double //)
            path2 = path2.replace(new RegExp("//+", "g"), "/");

            // Remove first char if it does not fit
            if(path2.charAt(0) === "/") {
                path2 = path2.substr(1);
            }

            path1 += path2;
        }

        return path1;
    };

    /**
     * Parse common data between method and class
     *
     * @param result {jerseyDocObject} The current object parsed for this path
     * @param data {Object} The server side object
    */
    function __parseDefault(result, data) {
        // Get the current showed path
        result.path = __concatPath(result.path, data.path);

        // ConsumeList && ProduceList
        if(a.isArray(data.consumeList) && data.consumeList.length > 0) {
            var i = data.consumeList.length;
            while(i--) {
                result.consumeList.push(data.consumeList);
            }
        }
        if(a.isArray(data.produceList) && data.produceList.length > 0) {
            var i = data.produceList.length;
            while(i--) {
                result.produceList.push(data.produceList);
            }
        }

        // Author & version
        if(__validString(data.author)) {
            result.author = data.author;
        }
        if(__validString(data.version)) {
            result.version = data.version;
        }

        // docList
        if(__validString(data.doc)) {
            result.docList.push(data.doc);
        }

        // Deprecated & unimplemented
        if(data.deprecated === true) {
            result.deprecated = true;
        }
        if(data.unimplemented === true) {
            result.unimplemented = true;
        }
    };

    /**
     * Parse data to get method presentation
     *
     * @param result {jerseyDocObject} The current object parsed for this path
     * @param data {Object} The server side object
    */
    function __parseMethod(result, data) {
        __parseDefault(result, data);

        if(__validString(data.name) && result.nameList.length > 0) {
            result.nameList[result.nameList.length - 1] += " | " + data.name;
        }


        // InputList
        result.inputList = result.inputList.concat(data.inputList);

        if(data.subResource === true) {
            return __parseClass(a.clone(result), data.output);
        } else {
            // Output
            result.output = data.output.name;

            // type
            result.type = convertType(data.type);

            // We can print data
            return result;
        }
    };

    /**
     * Parse data to get class presentation
     *
     * @param result {jerseyDocObject} The current object parsed for this path
     * @param data {Object} The server side object
    */
    function __parseClass(result, data) {
        __parseDefault(result, data);

        if(__validString(data.name)) {
            result.nameList.push(data.name);
        }

        // Getting method content
        var i = data.methodList.length,
            arr = [];
        while(i--) {
            var tmp = __parseMethod(a.clone(result), data.methodList[i]);
            if(a.isArray(tmp)) {
                arr = arr.concat(tmp);
            } else {
                arr.push(tmp);
            }
        }
        return arr;
    };


    /**
     * Main presentation parser to handle json content
     *
     * @param json {Object | array} Data recieve from server side
    */
    return function(json) {
        if(a.isNull(json)) {
            alert("Some data recieve where empty, can't proceed");
            return;
        }

        // Processing array as sub resource
        if(a.isArray(json)) {
            var i = json.length;
            while(i--) {
                jerseyDocPrettify(json[i]);
            }
            return;
        }

        if(a.isObject(json) && __detectClass(json)) {
            return __parseClass(a.clone(jerseyDocObject), json);
        } else {
            alert("unknow data given, can't proceed");
        }
    };
})();

<file_sep>package parking;

import java.util.List;

/**
 * 
 * @author <NAME>
 * Un �tage de parking contenant : 
 * - des places
 * - des itin�raires 
 *
 */
public class Etage {

	private List<Place> places;
	private List<Vecteur> chemins;
	
	/**
	 * Constructor
	 * @param places
	 * @param chemins
	 */
	public Etage(List<Place> places, List<Vecteur> chemins) {
		super();
		this.places = places;
		this.chemins = chemins;
	}
	
	/**
	 * @return the places
	 */
	public List<Place> getPlaces() {
		return places;
	}
	/**
	 * @param places the places to set
	 */
	public void setPlaces(List<Place> places) {
		this.places = places;
	}
	/**
	 * @return the chemins
	 */
	public List<Vecteur> getChemins() {
		return chemins;
	}
	/**
	 * @param chemins the chemins to set
	 */
	public void setChemins(List<Vecteur> chemins) {
		this.chemins = chemins;
	}
	
	
}
