GeoTools: insert custom Polygons into existiong .shp file - java

I'm new to Geotools. Now I want to insert a custom area (Polygon) in a Shapefile of Austria.
My code:
public static void main(String[] args) throws IOException {
File file = new File("src/main/java/org/geotools/austria.shp");
Map<String, Object> map = new HashMap<>();
map.put("url", file.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(map);
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source =
dataStore.getFeatureSource(typeName);
MapContent showmap = new MapContent();
showmap.setTitle("Austria");
Style style = SLD.createSimpleStyle(source.getSchema());
Layer layer = new FeatureLayer(source, style);
showmap.addLayer(layer);
// display the map
JMapFrame.showMap(showmap);
}
My current result:
This image shows my current output. I drew a red hexagon to show what I want to have in future.
How can I insert and display this Polygon into a Shapefile?

First you need to create a new Shapefile (you could overwrite the old one but it is easy to lose your data that way).
SimpleFeatureType TYPE = dataStore.getSchema(typeName);
File newFile = new File("output.shp");
ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put("url", URLs.fileToURL(newFile));
params.put("create spatial index", Boolean.TRUE);
ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
newDataStore.createSchema(TYPE);
Then you need to copy the existing polygons to the new file (I'm assuming they are in a SimpleFeatureCollection called collection) followed by the new feature(s):
Transaction transaction = new DefaultTransaction("create");
String typeName = newDataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
featureStore.setTransaction(transaction);
try {
featureStore.addFeatures(collection);
// Now add the hexagon
featureStore.addFeatures(DataUtilities.collection(hexagon));
transaction.commit();
} catch (Exception problem) {
problem.printStackTrace();
transaction.rollback();
System.exit(-1);
} finally {
transaction.close();
}
} else {
System.out.println(typeName + " does not support read/write access");
System.exit(1);
}

Related

Getting database values CODENAME ONE

I have an intermediate table that gets information from two other tables from the database (it gets their id), I'd like to show information of the other tables through that intermediate table in each of the others but it show me all of the information.
public showTheatreForm(Resources res, Theatre t) {
Toolbar tb=new Toolbar(true);
current=this;
setToolbar(tb);
getTitleArea().setUIID("Container");
setTitle("modifier actor");
getContentPane().setScrollVisible(false);
super.addSideMenu(res);
Label name = new Label((t.getName()));
Picker datePicker = new Picker();
datePicker.setDate(t.getRdate());
String datestring=(new SimpleDateFormat("yyyy-MM-dd")).format(datePicker.getDate());
Label date = new Label((datestring));
TextField description = new TextField((t.getDescription()));
TextField actors = new TextField((t.getTactor()));
//Label image = new Label((t.getImage()), "Image");
ImageViewer imavu;
try {
imavu = new ImageViewer(getImageFromServer(t.getImage()));
}
catch(Exception e) {
System.out.println(t.getImage());
imavu = new ImageViewer(res.getImage("s.png"));
}
description.setSingleLineTextArea(false);
actors.setSingleLineTextArea(false);
name.setUIID("NewsCenterLine");
date.setUIID("NewsCenterLine");
description.setUIID("NewsCenterLine");
imavu.setUIID("NewsCenterLine");
actors.setUIID("NewsCenterLine");
Label a = new Label("");
Label e = new Label ();
Container content = BoxLayout.encloseY(
e,a, (name),
createLineSeparator(), (actors),
createLineSeparator(),date,
createLineSeparator(), (description),
createLineSeparator(), (imavu)
);
add(content);
show();
}
And this is how I get it from the database:
public ArrayList<Theatre> ShowTheatre (){
ArrayList<Theatre> result=new ArrayList<>();
String url=Statics.BASE_URL+"/theatre/displayTheatre";
req.setUrl(url);
req.addResponseListener(new ActionListener<NetworkEvent>() {
#Override
public void actionPerformed(NetworkEvent evt) {
JSONParser Jsonp;
Jsonp=new JSONParser();
try{
Map<String,Object>mapTheatre= Jsonp.parseJSON(new CharArrayReader(new String(req.getResponseData()).toCharArray()));
List<Map<String,Object>> listofMaps = (List<Map<String,Object>>) mapTheatre.get("root");
for(Map<String,Object> obj : listofMaps)
{
Theatre th=new Theatre();
float id=Float.parseFloat(obj.get("id").toString());
String name=obj.get("name").toString();
String genre=obj.get("genre").toString();
String description=obj.get("description").toString();
String image=obj.get("image").toString();
String trailer=obj.get("trailer").toString();
String poster=obj.get("poster").toString();
String get=obj.get("theatreActors").toString();
th.setId((long)id);
th.setName(name);
th.setTactor(get);
System.out.println(get);
th.setDescription(description);
th.setImage(image);
th.setTrailer(trailer);
th.setPoster(poster);
th.setGenre(genre);
Map<String, Object> dd = (Map<String, Object>) obj.get("rdate");
float ll = Float.parseFloat(dd.get("timestamp").toString());
th.setRdate(new Date(((long) ll * 1000)));
}
result.add(th);
}
} catch (IOException ex) {
System.out.println(
"good");
}
}
});
NetworkManager.getInstance().addToQueueAndWait(req);
return result;
}
Result of the code
This is the result, but I only want to get the "name" and "date" or "description" from the intermediate table
My intermediate table
(the name of the table is theatreActors)

Geotools PolygonExtractionProcess is not working

I want to convert a raster file into a shapefile. I am creating a GridCoverage2D object and want to use the execute method of Geotools PolygonExtractionProcess class but this method is not executing. I sadly cannot find any useful example usages of this class. This is my code:
try {
File rasterFile = new File("C:\\Data\\mytif.tif");
AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);
Hints hints = new Hints();
if (format instanceof GeoTiffFormat) {
hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
}
reader = format.getReader(rasterFile, hints);
GridCoverage2D coverage = reader.read(null); // It all works until this point
final PolygonExtractionProcess process = new PolygonExtractionProcess();
//System.out.println("This gets printed");
SimpleFeatureCollection sfColl = process.execute(coverage, null, Boolean.TRUE, null, null, null, null);
//System.out.println("This does not get printed anymore");
Style style = SLD.createPolygonStyle(Color.RED, null, 0.0f);
Layer layer = new FeatureLayer(sfColl, style);
map.addLayer(layer);
} catch (Exception e) {
System.err.println(e);
}
First, if all you want to do is extract vectors from a raster you could probably save using the process API completely by looking inside PolygonExtractionProcess to see how it works using the JAI.
But if you want to run a process then you should read the process tutorial which describes how they work and how to call them from your own code (this is usually used for testing). Essentially, the issue you are having comes from not understanding that processes are called from the processing engine (ProcessExecutor) which manages the input and output, and threading etc for you.
So your code should look something like this:
public class RasterToVector {
public static void main(String[] args)
throws IllegalArgumentException, IOException, InterruptedException, ExecutionException {
RasterToVector rtv = new RasterToVector();
SimpleFeatureCollection features = rtv.extract(args[0]);
Style style = SLD.createPolygonStyle(Color.RED, null, 0.0f);
Layer layer = new FeatureLayer(features, style);
MapContent map = new MapContent();
map.addLayer(layer);
JMapFrame.showMap(map);
}
org.geotools.process.Process process;
public RasterToVector() {
Name name = new NameImpl("ras", "PolygonExtraction");
process = Processors.createProcess(name);
}
private SimpleFeatureCollection extract(String filename)
throws IllegalArgumentException, IOException, InterruptedException, ExecutionException {
File rasterFile = new File(filename);
AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);
Hints hints = new Hints();
if (format instanceof GeoTiffFormat) {
hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
}
AbstractGridCoverage2DReader reader = format.getReader(rasterFile, hints);
GridCoverage2D coverage = reader.read(null);
ProcessExecutor engine = Processors.newProcessExecutor(2);
Map<String, Object> input = new KVP("data", coverage);
Progress working = engine.submit(process, input);
Map<String, Object> result = working.get();
SimpleFeatureCollection features = (SimpleFeatureCollection) result.get("result");
return features;
}
}
For a local terrain file I get the following result:

Saving / Loading HashMap<String, Integer> into file.txt

I would love to know how can I save and load my HashMap from a file called data.txt , I'm already using a method to save and load the HashMap from a config.yml (which i will show you below).
Here is my HashMap
HashMap<String, Integer> points = new HashMap<String, Integer>();
This is my saving method for the HashMap from the config.yml
public void savePoints(){
for (Entry<String, Integer> pointstostore : points.entrySet()) {
getConfig().set(pointstostore.getKey(), pointstostore.getValue());
}
saveConfig();
}
This is my loading method for the HashMap from the config.yml
public void loadPoints(){
for (String str : getConfig().getKeys(true)) {
int p = getConfig().getInt(str);
points.put(str, p);
}
}
The config.yml is structured like that in a yaml format
playername: points
playername2: points
...
Is there any way for me to create a new file called data.txt from which I can save and load the HashMap points for every player and request from each player the amount of points they have and the file to have the following or a similar format
players:
points:
playername: points
playername2: points
...
Do it by using a Properties.
To write:
Properties p = new Properties();
p.putAll(points):
try (FileOutputStream fos = new FileOutputStream("file.txt");) {
p.store(fos, null);
}
To read:
Properties p = new Properties();
try (FileInputStream fos = new FileInputStream("file.txt");) {
p.load(fos);
points = new Hasmap<>(p);
}
To make a new .yml file you do:
public class Main {
private File datafile;
private FileConfiguration data;
public void onEnable() {
datafile = new File(getDataFolder(), "data.yml");
data = YamlConfiguration.loadConfiguration(datafile);
saveDataYml();
}
public static void saveDataYml() {
try{
data.save(datafile);
}catch(Exception e){
e.printStackTrace();
}
}
public static FileConfiguration getDataYml() {
return data;
}
}

JasperReports API: How to pass multiple parameters to report

I am using JasperReports API to print from my Java application. I am printing a report like this:
public void prints(String billNo, String fileName, String outFileName, String perameterName) {
HashMap hm = new HashMap();
hm.put(perameterName, billNo);
//Here parameterName is the parameter in JasperReport.
// billNo is the value from my java application.
try {
conn = new connection().db();
PrinterJob job = PrinterJob.getPrinterJob();
/* Create an array of PrintServices */
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
PrintService default_service = PrintServiceLookup.lookupDefaultPrintService();
int selectedService = 0;
/* Scan found services to see if anyone suits our needs */
for (int i = 0; i < services.length; i++) {
if (services[i].getName().toUpperCase().equals(default_service.getName().toUpperCase())) {
selectedService = i;
}
}
job.setPrintService(services[selectedService]);
PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
printRequestAttributeSet.add(MediaSizeName.ISO_A4);
printRequestAttributeSet.add(new Copies(1));
JRPrintServiceExporter exporter;
exporter = new JRPrintServiceExporter();
JasperPrint print = JasperFillManager.fillReport(fileName, hm, conn);
JRExporter exporterr = new JRPdfExporter();
exporterr.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outFileName);
exporterr.setParameter(JRExporterParameter.JASPER_PRINT, print);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE, services[selectedService]);
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET, services[selectedService].getAttributes());
exporter.setParameter(JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET, printRequestAttributeSet);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG, Boolean.FALSE);
exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.FALSE);
exporter.exportReport();
exporterr.exportReport();
} catch (JRException e) {
JOptionPane.showMessageDialog(null, e);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Printer not connected. Check power cable.");
}
}
I use to invoke this method in other classes.
But how can I pass multiple Parameters and multiple values to report?
for example query:
"select * from table1 where date>"+thisDate+" and date<"+thatDate+" "
How can I send thisDate and thatDate from my Java application?
Since you are using a HashMap you can store there many values. You can do it like:
HashMap hm = new HashMap();
hm.put(perameterName, billNo);
hm.put("thisDate", thisDate);
hm.put("theDate", theDate);
hm.put("anotherParam", paramValue);
If you don't want your method to pass so many keys and values as arguments, you can simply pass the "hm" object to your method:
public void prints( String fileName, String outFileName, HashMap hm){

How to specify the subdataset query when executing report from a Java application

I have a main report with a main query and a Table (with subdataset) inside of it, which has its own Query.
I know how to specify the Query for the main report, but I don't know how the to specify Query for the subdatset in my Java code of creation reports.
Can anyone help, please ?
My code:
public static java.sql.Connection cx = Connexion.SetConOn();
public static void Create report(String Query, String model, String title, String art) {
try {
JRDesignQuery jrd = new JRDesignQuery();
JasperDesign design = JRXmlLoader.load(model);
jrd.setText(Query);
design.setQuery(jrd);
Map map = new HashMap();
JasperReport etat = JasperCompileManager.compileReport(design);
JasperPrint print = JasperFillManager.fillReport(etat, map, cx);
File f = new File("C:\\" + fdg);
f.mkdir();
JasperExportManager.exportReportToPdfFile(print, f.getPath() + "\\" + title + ".pdf");
JasperViewer jv = new JasperViewer(print, false, Locale.FRENCH);
try {
java.awt.image.BufferedImage bi = javax.imageio.ImageIO.read(jv.getClass().getResource("/cycloplan/Images/Burn-icon1.png"));
javax.swing.ImageIcon myImg = new javax.swing.ImageIcon(bi);
jv.setIconImage(myImg.getImage());
} catch (java.io.IOException ex) {
ex.printStackTrace();
}
jv.setTitle(title);
jv.setAlwaysOnTop(true);
jv.setVisible(true);
} catch (JRException ex) {
ex.printStackTrace();
}
}
The JasperDesign class has a few different ways to access subdatasets; take a look at the javadoc [link]. I think the following code should work to set the subdataset query, where subQueryString is the query you want to use and datasetName is the name given to the subdataset element in the JRXML.
JRDesignQuery subQuery = new JRDesignQuery();
subQuery.setText(subQueryString);
Map<String, JRDataset> datasetMap = design.getDatasetMap();
JRDesignDataset subDataset = (JRDesignDataset) datasetMap.get(datasetName);
subDataset.setQuery(subQuery);
(* I haven't actually tested this code. YMMV)

Categories