Now, I am trying to use the proximity search in Geomodel. However, I
am facing a problem, which I am not sure what it is, but I think it is
related to either my PersistentManager or baseQuery. I ran the query,
however, while my database is not empty, I got null results.
public class HowToUseGeocell extends TestCase {
...
public int ProximitySearch(double lat, double lon, double distance) {
Point center = new Point(lat, lon);
List<ObjectToSave> objects = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
try{
List<Object> params = new ArrayList<Object>();
params.add("Mahsa");
GeocellQuery baseQuery = new GeocellQuery("Owner ==
OwnerParam", "String OwnerParam", params);
try {
objects = GeocellManager.proximityFetch(center, 40,
distance, ObjectToSave.class, baseQuery, pm);
Assert.assertTrue(objects.size() > 0);
} catch (Exception e) {
// We catch excption here because we have not
configured the PersistentManager (and so the queries won't work)
}
} finally {
pm.close();
}
if (objects == null)
return -3;
else
return objects.size();
}
}
Here is my ObjectToSave class:
@PersistenceCapable(detachable="true")
public class ObjectToSave implements LocationCapable {
@PrimaryKey
@Persistent
private long id;
@Persistent
private double latitude;
@Persistent
private double longitude;
@Persistent
private double altitude;
@Persistent
private List<String> geocells;
@Persistent
private String owner;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getAltitude() {
return altitude;
}
public void setAltitude(double alt) {
this.altitude = alt;
}
public List<String> getGeocells() {
return geocells;
}
public void setGeocells(List<String> geocells) {
this.geocells = geocells;
}
public String getKeyString() {
return Long.valueOf(id).toString();
}
public Point getLocation() {
return new Point(latitude, longitude);
}
public String getOwner() {
return owner;
}
public void setOwner(String o) {
this.owner = o;
}
}
My PMF class:
public final class PMF {
private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-
optional");
private PMF() {}
public static PersistenceManagerFactory get() {
return pmfInstance;
}
}
My Servlet:
@SuppressWarnings("serial")
public class Test8_Geomodel_GAEServlet extends HttpServlet {
// public static UseGeocell GC = new UseGeocell();
//public final static PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
doPost(req, resp);
// resp.setContentType("text/plain");
// resp.getWriter().println("Hello, world");
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
HowToUseGeocell gc = new HowToUseGeocell();
List<ObjectToSave> obj = new ArrayList<ObjectToSave>();
//Read Excel "source file" (which is defined in web.xml file) &
store it in datastore
ServletContext context = getServletContext();
String file_path = context.getRealPath("LiDAR.xls");
File Myfile = new File(file_path);
Workbook workBook;
int PointNo;
double latitude = 0.0, longitude = 0.0, altitude = 0.0;
String owner = "";
try {
workBook = Workbook.getWorkbook(Myfile);
Sheet sheet = workBook.getSheet(0);
int NumOfColumns = sheet.getColumns();
int NumOfRows = sheet.getRows();
String data;
for(int row = 1; row < NumOfRows; row++) {
for(int col = 0; col < NumOfColumns; col++) {
data = sheet.getCell(col, row).getContents();
data = sheet.getCell(0,
row).getContents();
PointNo =
Integer.parseInt(data.toString());
data = sheet.getCell(1,
row).getContents();
owner = data;
data = sheet.getCell(2,
row).getContents();
latitude =
Double.parseDouble(data.toString());
data = sheet.getCell(3,
row).getContents();
longitude =
Double.parseDouble(data.toString());
data = sheet.getCell(4,
row).getContents();
altitude =
Double.parseDouble(data.toString());
gc.SaveGeocellsInDatabase(latitude,
longitude, altitude, owner);
}
}
} catch (BiffException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Reading input entries & executing
proximity query
String lat =
req.getParameter("txtlatitude_prox");
String lon =
req.getParameter("txtlongitude_prox");
String dis =
req.getParameter("txtdistance_prox");
double Latitude =
Double.parseDouble(lat);
double Longitude =
Double.parseDouble(lon);
double Distance =
Double.parseDouble(dis);
int size = gc.ProximitySearch(Latitude,
Longitude, Distance);
String res_size =
Integer.toString(size);
resp.setContentType("text/plain");
resp.getWriter().println(res_size);
}
}
Finally, here is my database (LiDAR.xls file) which is saved in /WAR
and is defined in web.xml file as a resource file as follow:
<resource-files>
<include path="/**.xls" />
</resource-files>
point_no Owner lat long
alt
1 Mahsa 40.46231168 -79.97302985 232.8336705
2 Mahsa 40.46229439 -79.97302785 240.4475744
3 Mahsa 40.46227221 -79.97302604 241.3772144
4 Mahsa 40.46224956 -79.97302421 242.0813024
When I run the program (in a browser), using any lat, lon, & distance,
it returns -3 as the size of the query results, which shows that the
query result was null. I am not sure what I am doing wrong. I really
appreciate if I get help with this.
Also, I appreciate it if someone clarifies what baseQuery is used for.
My understanding is that it first executes a query on the database and
then executes proximity query on the result of the first query
(baseQuery). Is that correct?
Thanks in advance & sorry if my questions sound simple. I am very new
to GAE & java/servlet web development.
On Jul 18, 12:13 pm, Mahsa <[email protected]> wrote:
> Hi Stephen,
>
> Thanks for your help. The problem has been solved by adding the
> libraries into the class path.
>
> On Jul 16, 7:33 pm, Stephen Johnson <[email protected]> wrote:
>
> > Hi Mahsa,
>
> > You have these imports:
> > import com.beoui.geocell.GeocellManager;
> > import com.beoui.geocell.model.BoundingBox;
> > import com.beoui.geocell.model.CostFunction;
> > import com.beoui.geocell.model.GeocellQuery;
> > import com.beoui.geocell.model.Point;
>
> > So, one obvious question since you are getting NoClassDefFoundError:
> > com/beoui/geocell/model/Point is: Did you put the appropriate JAR file
> > in WEB-INF/lib or if these classes are not in a JAR, did you put them
> > in WEB-INF/classes directory?
>
> > Stephen Johnson
>
> > On Jul 13, 1:13 pm, Mahsa <[email protected]> wrote:
>
> > > Hello,
>
> > > I am developing a simple GIS cloud application using Google App Engine
> > > & Geomodel. In this application, I would like to store latitude and
> > > longitude of points from user, & later on query them using boundingbox
> > > & proximity queries. I am experiencing problem while trying to access
> > > the server through a browser. I appreciate it if someone help me with
> > > this regard.
>
> > > I am usingEclipse, and here is what I did:
>
> > > 1) Created a Web application project enabling only Google App Engine
> > > (1.3.4)(as Google SDK)
>
> > > 2) Created a simple jsp file in "war" folder to get latitude &
> > > longitude from user
>
> > > 3) Created two java classes, UseGeocell and ObjectToSave. UseGeocell
> > > class is similar to the code
> > > inhttp://code.google.com/p/javageomodel/source/browse/trunk/geocell/src...
> > > ObjectToSave is
> > > exactlyhttp://code.google.com/p/javageomodel/source/browse/trunk/geocell/src...
>
> > > 4)In my Servlet I defined an object of type UseGeocell and called
> > > testHowToSaveGeocellsInDatabase function in order to save latitude &
> > > longitude that are obtained from the input
>
> > > Here is my code:
>
> > > My UseGeocell class:
>
> > > package edu.pitt.Test8_Geomodel_GAE;
>
> > > import java.util.ArrayList;
> > > import java.util.List;
> > > import java.util.logging.Level;
> > > import java.util.logging.Logger;
>
> > > import javax.jdo.PersistenceManager;
>
> > > import junit.framework.Assert;
> > > import junit.framework.TestCase;
>
> > > import com.beoui.geocell.GeocellManager;
> > > import com.beoui.geocell.model.BoundingBox;
> > > import com.beoui.geocell.model.CostFunction;
> > > import com.beoui.geocell.model.GeocellQuery;
> > > import com.beoui.geocell.model.Point;
>
> > > /**
> > > * Unit test also used to explain how to use Geocell class.
> > > *
> > > * @author Alexandre Gellibert <[email protected]>
> > > *
> > > */
> > > public class UseGeocell extends TestCase {
>
> > > private final Logger log =
> > > Logger.getLogger("com.beoui.utils");
> > > public ObjectToSave obj;
>
> > > /**
> > > * First step is to save your entities.
> > > * In database, you don't save only latitude and longitude of
> > > your point but also geocells around this point.
> > > */
> > > public void testHowToSaveGeocellsInDatabase(double lat, double
> > > lon) {
> > > // Incoming data: latitude and longitude (Bordeaux for
> > > instance)
> > > //double lat = 44.838611;
> > > //double lon = -0.578333;
>
> > > // Transform it to a point
> > > Point p = new Point(lat, lon);
>
> > > // Generates the list of GeoCells
> > > List<String> cells = GeocellManager.generateGeoCell(p);
>
> > > // Save your instance
> > > obj = new ObjectToSave();
> > > obj.setLatitude(lat);
> > > obj.setLongitude(lon);
> > > obj.setGeocells(cells);
>
> > > //objDao.save(obj);
>
> > > // Just checking that cells are not empty
> > > Assert.assertTrue(cells.size() > 0);
>
> > > // Show in the log what cells are going to be saved
> > > log.log(Level.INFO, "Geocells to be saved for Point("+lat
> > > +","+lon+") are: "+cells);
> > > }
>
> > > /**
> > > * Second step, now entities are in database, we can query on
> > > them.
> > > * Here is the example of a bounding box query.
> > > *
> > > */
> > > public void testHowToQueryOnABoundingBox(double latSW, double
> > > lonSW, double latNE, double lonNE) {
> > > // Incoming data: latitude and longitude of south-west and
> > > north-east points (around Bordeaux for instance =) )
> > > //double latSW = 44.8;
> > > //double lonSW = -0.6;
>
> > > // double latNE = 44.9;
> > > // double lonNE = -0.7;
>
> > > // Transform this to a bounding box
> > > BoundingBox bb = new BoundingBox(latNE, lonNE, latSW,
> > > lonSW);
>
> > > // Calculate the geocells list to be used in the queries
> > > (optimize list of cells that complete the given bounding box)
> > > List<String> cells =
> > > GeocellManager.bestBboxSearchCells(bb,
> > > null);
>
> > > // OR if you want to use a custom "cost function"
> > > List<String> cells2 =
> > > GeocellManager.bestBboxSearchCells(bb,
> > > new CostFunction() {
>
> > > @Override
> > > public double defaultCostFunction(int numCells, int
> > > resolution) {
> > > if(numCells > 100) {
> > > return Double.MAX_VALUE;
> > > } else {
> > > return 0;
> > > }
> > > }
> > > });
>
> > > // Use this in a query
> > > // In Google App Engine, you'll have something like
> > > below. In
> > > hibernate (or whatever else), it might be a little bit different.
> > > // String queryString = "select from ObjectToSave where
> > > geocellsParameter.contains(geocells)";
> > > // Query query = pm.newQuery(query);
> > > // query.declareParameters("String geocellsParameter");
> > > // query.declareParameters("String geocellsP");
> > > // List<ObjectToSave> objects = (List<ObjectToSave>)
> > > query.execute(cells);
>
> > > // Just checking that cells are not empty
> > > Assert.assertTrue(cells.size() > 0);
> > > Assert.assertTrue(cells2.size() > 0);
>
> > > // Show in the log what cells shoud be used in the query
> > > log.log(Level.INFO, "Geocells to use in query for
> > > PointSW("+latSW+","+lonSW+") ; PointNE("+latNE+","+lonNE+") are:
> > > "+cells);
> > > }
>
> > > /**
> > > * To test proximity search, you have to give your base query
> > > and
> > > it will be enhanced with geocells restrictions.
> > > *
> > > */
> > > // TODO configure persistent manager to run a real test
> > > public void testHowToQueryWithProximitySearch(double lat,
> > > double
> > > lon) {
> > > Point center = new Point(lat, lon);
> > > PersistenceManager pm = null;// here put your persistent
> > > manager
> > > List<Object> params = new ArrayList<Object>();
> > > params.add("John");
> > > GeocellQuery baseQuery = new GeocellQuery("lastName ==
> > > lastNameParam", "String lastNameParam", params);
>
> > > List<ObjectToSave> objects = null;
> > > try {
> > > objects = GeocellManager.proximityFetch(center, 40, 0,
> > > ObjectToSave.class, baseQuery, pm);
> > > Assert.assertTrue(objects.size() > 0);
> > > } catch (Exception e) {
> > > // We catch exception here because we have not
> > > configured
> > > the PersistentManager (and so the queries won't work)
> > > }
> > > }
>
> > > }
>
> > > My servlet:
>
> > > package edu.pitt.Test8_Geomodel_GAE;
>
> > > import java.io.IOException;
> > > import javax.servlet.http.*;
>
> > > @SuppressWarnings("serial")
> > > public class Test8_Geomodel_GAEServlet extends HttpServlet {
> > > public void doGet(HttpServletRequest req, HttpServletResponse
> > > resp)
> > > throws IOException {
>
> > > doPost(req, resp);
> > > }
>
> > > public void doPost(HttpServletRequest req, HttpServletResponse
> > > resp)
> > > throws IOException {
> > > String lat = req.getParameter("txtlatitude");
> > > String lon = req.getParameter("txtlongitude");
>
> > > double latitude =
>
> ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en.