I have saved Picasa's face data inside my JPEG files (in XMP) and now I am trying to read that information in Java. So far I am failing and help would be much appreciated.
I am trying to use metadata-extractor library (though any other solution would also be fine). I can read the basic information (like the date, the image size etc.), but I am lost at extracting the additional data. This is what I get so far:
File file -- this is my JPEG file
Metadata metadata = JpegMetadataReader.readMetadata(file);
XmpDirectory xmpDirectory = metadata.getDirectory(XmpDirectory.class);
XMPMeta xmpMeta = xmpDirectory.getXMPMeta();
System.out.println(xmpMeta.dumpObject());
Result:
ROOT NODE
http://www.metadataworkinggroup.com/schemas/regions/ = "mwg-rs:" (0x80000000 : SCHEMA_NODE)
mwg-rs:Regions (0x100 : STRUCT)
mwg-rs:AppliedToDimensions (0x100 : STRUCT)
stDim:h = "2793"
stDim:unit = "pixel"
stDim:w = "2047"
mwg-rs:RegionList (0x200 : ARRAY)
[1] (0x100 : STRUCT)
mwg-rs:Area (0x100 : STRUCT)
stArea:h = "0.69531"
stArea:unit = "normalized"
stArea:w = "0.790425"
stArea:x = "0.491451"
stArea:y = "0.41783"
mwg-rs:Name = "abcde"
mwg-rs:Type = "Face"
http://ns.adobe.com/xap/1.0/ = "xmp:" (0x80000000 : SCHEMA_NODE)
xmp:ModifyDate = "2014-04-06T19:43:24+01:00"
I do not understand how to get to these stArea:w, mwg-rs:Type = "Face", etc.
As usual, right after posting I've found a solution. I'll list it below to have it here.
try {
Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
XmpDirectory xmpDirectory = metadata.getDirectory(XmpDirectory.class);
XMPMeta xmpMeta = xmpDirectory.getXMPMeta();
XMPIterator itr = xmpMeta.iterator();
while (itr.hasNext()) {
XMPPropertyInfo pi = (XMPPropertyInfo) itr.next();
if (pi != null && pi.getPath() != null) {
if ((pi.getPath().endsWith("stArea:w")) || (pi.getPath().endsWith("mwg-rs:Name")) || (pi.getPath().endsWith("stArea:h")))
System.out.println(pi.getValue().toString());
}
}
} catch (final NullPointerException npe) {
// ignore
}
What I do not like here is that it iterates through all properties instead of just reading the required ones. Any better (faster) solution?
Related
I am new to shapefile processing. Kindly guide me on how to achieve my below query.
I am using this shapefile tl_2018_us_aiannh.shp from census.gov : TIGER-LINE. I am to obtain the census block group entities like Block, Tract, County subdivision and County details from the shapefile based on the latitude and longitude provided by the user.
My requirement is to achieve this by shapefile alone and not through any API's.
Can someone help on which framework I can achieve this?
What I've tried/using so far:
I have used GeoTools to read the shapefile . Can I continue using the same? Will my requirement be achievable by this tool?
I have gone through a documentation from census.gov which states:
The Census Bureau assigns a code and these appear in fields such as
“TRACTCE”, where “CE” stands for Census. Finally, state-submitted
codes end in “ST”, such as “SLDLST”, and local education agency codes
end in “LEA”, as in “ELSDLEA”.
Which I tried in my code by:
File file = new File("D:\\tl_2018_us_aiannh.shp");
try {
Map<String, String> connect = new HashMap();
connect.put("url", file.toURI().toString());
DataStore dataStore = DataStoreFinder.getDataStore(connect);
String[] typeNames = dataStore.getTypeNames();
String typeName = typeNames[0];
System.out.println("Reading content " + typeName);
SimpleFeatureSource featureSource = dataStore
.getFeatureSource(typeName);
SimpleFeatureCollection collection = featureSource.getFeatures();
SimpleFeatureIterator iterator = collection.features();
try {
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
GeometryAttribute sourceGeometry = feature
.getDefaultGeometryProperty();
String name = (String) (feature).getAttribute("TRACTCE");
Property property = feature.getProperty("TRACTCE");
System.out.println(property);
}
} finally {
iterator.close();
}
} catch (Throwable e) {
e.getMessage();
}
But I am receiving null as the value.
Any help would be much helpful.
I have found the solution to this. Hope this would be helpful to someone in need.
SimpleFeature is the type that has the attributes of shape files that you can check when you try to debug or print a line on runtime. You can use the SimpleFeature to get the property. The attributes can be achieved by:
try {
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Property intptlat = feature.getProperty("TRACTCE");
}
}
Make sure you are choosing the Block Groups as the layer type for download in Tiger-Line or which ever site is concerned, where you download the shape file.
I have two lists of type List<A> and List<B>. Now, what I'm trying to do is to create a List<C>, the values of which would be read from other two lists. I tried and implemented something like this.
public void fileUpload(int customerId) throws SQLException, IOException {
myList = myTiedosto.getFileDetails(customerId);
attachmentDetails = myAttachment.getAttachmentDetails(customerId);
List<Upload> uploadList = new ArrayList<>();
for (Attachment attachment : attachmentDetails) {
Upload upload = new Upload();
upload.setUuid(attachment.getUuid());
for (Tiedosto tiedosto : myList) {
upload.setCustomerId(tiedosto.getCustomerId());
upload.setFileName(tiedosto.getFileName());
upload.setFileSize(tiedosto.getFileSize());
upload.setContent(tiedosto.getContent());
}
uploadList.add(upload);
}
for (Upload myUploadList : uploadList) {
System.out.println(myUploadList.getCustomerId()+" " +myUploadList.getFileName()+" "+myUploadList.getUuid()+" "+myUploadList.getFileSize());
}
}
When I run this, myUploadList returns the same entry twice.
output
I'm a newbie in Java, I'd really appreciate some help.
Based on your comment, you should create and add the Upload instance to the output List inside the inner loop:
for (Attachment attachment : attachmentDetails) {
for (Tiedosto tiedosto : myList) {
Upload upload = new Upload();
upload.setUuid(attachment.getUuid());
upload.setCustomerId(tiedosto.getCustomerId());
upload.setFileName(tiedosto.getFileName());
upload.setFileSize(tiedosto.getFileSize());
upload.setContent(tiedosto.getContent());
uploadList.add(upload);
}
}
This will create an Upload instance from each pair of Attachment and Tiedosto.
EDIT:
Based on your latest comment, it would be better to use traditional for loop, since you want to create an Upload instance from each pair of Attachment and Tiedosto instances having the same index:
for (int i = 0 ; i < attachmentDetails.size(); i++) {
Tiedosto tiedosto = myList.get(i);
Upload upload = new Upload();
upload.setUuid(attachmentDetails.get(i).getUuid());
upload.setCustomerId(tiedosto.getCustomerId());
upload.setFileName(tiedosto.getFileName());
upload.setFileSize(tiedosto.getFileSize());
upload.setContent(tiedosto.getContent());
uploadList.add(upload);
}
After reading your comments, I think this is what you want.
int i = 0;
for (Attachment attachment : attachmentDetails) {
Upload upload = new Upload();
upload.setUuid(attachment.getUuid());
upload.setCustomerId(myList.get(i).getCustomerId());
upload.setFileName(myList.get(i).getFileName());
upload.setFileSize(myList.get(i).getFileSize());
upload.setContent(myList.get(i).getContent());
uploadList.add(upload);
i++;
}
or if you have a way of identifying which if the myList belongs to which attachment then you can loop through the myList and do a check:
for (Attachment attachment : attachmentDetails) {
Upload upload = new Upload();
upload.setUuid(attachment.getUuid());
for (Tiedosto tiedosto : myList) {
if(tiedosto.getCustomerId() == attachment.getId()//assuming you have this field
upload.setCustomerId(tiedosto.getCustomerId());
upload.setFileName(tiedosto.getFileName());
upload.setFileSize(tiedosto.getFileSize());
upload.setContent(tiedosto.getContent());
}
uploadList.add(upload);
}
The entries are not same as both have different UUID. The other details such as CustomerId,Filename, Filesize etc. are same as you are iterating the same myList for each iteration row of the list myAttachment. So, verify whether you are iterating correct with respect to the expected data
Man, It's a logical problem in your program.
I guess it's caused by the inner cycle.
It's overwriting the upload with the last element myList's information. Maybe that's why you have exactly the same information in all the fields, except for the uuid.
Can anyone give me advice on how to read the general ledger using SuiteTalk, the SOAP API from NetSuite?
For example, if you look at an account or a transaction on the NetSuite UI, there is an option to select "GL Impact". This produces a list of relevant general ledger entries.
However, I couldn't figure out a way to get the same list using SuiteTalk. One initially promising SOAP operation I tried calling was getPostingTransactionSummary(), but that is just a summary and lacks detail such as transaction dates. Another way is to call search() passing a TransactionSearchBasic object. That returns too many types of transaction and I'm not sure which of those actually have an impact on the general ledger.
I'm using Java and Axis toolkit for the SOAP operations, but examples in any language whatsoever (or raw SOAP XML) would be appreciated.
you are on the right track with your transaction search.
You are looking for posting is true and where the line has an account.
However I'd set this up in the saved search editor at least until you've figured out how you are going to filter to manageable numbers of lines. Then use TransactionSearchAdvanced with savedSearchId to pull that info via SuiteTalk
I am able to search GL transaction with below code, this could help you.
public void GetTransactionData()
{
DataTable dtData = new DataTable();
string errorMsg = "";
LoginToService(ref errorMsg);
TransactionSearch objTransSearch = new TransactionSearch();
TransactionSearchBasic objTransSearchBasic = new TransactionSearchBasic();
SearchEnumMultiSelectField semsf = new SearchEnumMultiSelectField();
semsf.#operator = SearchEnumMultiSelectFieldOperator.anyOf;
semsf.operatorSpecified = true;
semsf.searchValue = new string[] { "Journal" };
objTransSearchBasic.type = semsf;
objTransSearchBasic.postingPeriod = new RecordRef() { internalId = "43" };
objTransSearch.basic = objTransSearchBasic;
//Set Search Preferences
SearchPreferences _searchPreferences = new SearchPreferences();
Preferences _prefs = new Preferences();
_serviceInstance.preferences = _prefs;
_serviceInstance.searchPreferences = _searchPreferences;
_searchPreferences.pageSize = 1000;
_searchPreferences.pageSizeSpecified = true;
_searchPreferences.bodyFieldsOnly = false;
//Set Search Preferences
try
{
SearchResult result = _serviceInstance.search(objTransSearch);
List<JournalEntry> lstJEntry = new List<JournalEntry>();
List<JournalEntryLine> lstLineItems = new List<JournalEntryLine>();
if (result.status.isSuccess)
{
for (int i = 0; i <= result.recordList.Length - 1; i += 1)
{
JournalEntry JEntry = (JournalEntry)result.recordList[i];
lstJEntry.Add((JournalEntry)result.recordList[i]);
if (JEntry.lineList != null)
{
foreach (JournalEntryLine line in JEntry.lineList.line)
{
lstLineItems.Add(line);
}
}
}
}
try
{
_serviceInstance.logout();
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{
throw ex;
}
}
Im working with exporting and importing Orient DB using java. I could export a whole database. But when i specify to export a specified class it export that class only. Sub classes are not exported. Here is the code:
ODatabaseDocumentTx db = new ODatabaseDocumentTx("remote:localhost/sampleDataBase").open("admin", "admin");
ODatabaseExport export = new ODatabaseExport(db, "DataCont/FinalTry.gz", listener);
Set<String> a= new HashSet<String>();
a.add("Employee".toUpperCase());
export.setIncludeClasses(a);
export.exportDatabase();
export.close();
So is this suppose to be or am i doing anything wrong?
Checking the source code for ODatabaseExport it does seem that it only takes clusters/records which are exactly of the type specified with setIncludeClasses(). For instance in exportRecords():
ODocument doc = (ODocument) rec;
final String className = doc.getClassName() != null ? doc.getClassName().toUpperCase() : null;
if (includeClasses != null) {
if (!includeClasses.contains(className))
continue;
} else if (excludeClasses != null) {
if (excludeClasses.contains(className))
continue;
}
They have similar checks in several other places in that class. This would mean that you need to put into the a set all the classes you want to export yourself.
You can add this piece of code if want to export all subclasses too:
Set<String> classesToExport = new HashSet<>();
classesToExport.add("Employee".toUpperCase());
OSchema oSchema = db.getMetadata().getSchema();
for (String className : classesToExport) {
OClass clazz = oSchema.getClass(className);
for(OClass subClass : clazz.getAllBaseClasses()){
//String subClassName = subClass.getName();
String subClassName = subClass.getName().toUpperCase();
if(!classesToExport.contains(subClassName)){
classesToExport.add(subClassName);
}
}
}
How can I delete the saved content in eclipse secure storage programmatically? I need to reset all setting before I run some SWTBot tests.
I know, that I can delete the folder, but isn't there another way?
../.eclipse/org.eclipse.equinox.security
EDIT:
Thanks to Kris I solved the problem.
//part 1
try {
AuthPlugin.getDefault().stop(null);
} catch (final Exception e) {
e.printStackTrace();
}
//part 2
final ISecurePreferences rootNode = SecurePreferencesFactory.getDefault()
.node(ROOT_NODE_NAME);
final String[] names = rootNode.childrenNames().clone();
for (int i = 0; i < names.length; i++) {
rootNode.node(names[i]).removeNode();
}
The problem is solved in part 2. I want to also show a way how to stop the authentication for the secure storage, because it is very annoying, by testing with SWTBot.
You can remove stored values in secure store by using ISecurePreferences. Have a look here
ISecurePreferences root = org.eclipse.equinox.security.storage.SecurePreferencesFactory.getDefault();
if (root == null)
return null;
ISecurePreferences node = root.node("/your.class.path.or.something.else"); // get the node for your application e.g. this.getClass().getCanonicalName()
node = node.node( "some name"); // get custom node from the tree
node.get( "key" ); // load
node.put("key","value", true / false (encrypt) ); // store (no save operation)
node.remove("key"); // remove
node.flush(); // save