Accessing nested JSON in Processing - json

I need to extract 3 values from a JSON file. I just managed to get all data but I can't separate them.
The file looks like this:
{
"motionAndDeviceRelated":{
"mOrientation":[0,0,0],
"mLocalVelocity":[0,0,0],
"mWorldVelocity":[0,0,0],
"mAngularVelocity":[0,0,0],
"mLocalAcceleration":[0,0,0],
"mWorldAcceleration":[0,0,0],
"mExtentsCentre":[0,0,0]
}
}
I need to extract in float variables data from mLocalAcceleration.
import http.requests.*;
JSONObject json;
void setup() {
size(600,600);
}
void draw() {
// actually returns something instead of throwing an error, which is progress
long t = System.currentTimeMillis();
GetRequest get = new GetRequest("http://" + "localhost:8180/crest2/v1/api?motionDeviceRelated=true&formatted=true");
get.send();
JSONObject json = parseJSONObject(get.getContent());
println(json);
println(System.currentTimeMillis() - t);
loop();
}

Here is the code that works:
`import http.requests.*;
JSONObject json;
float x;
float y;
float z;
void setup() {
size(800,800);
}
void draw() {
long t = System.currentTimeMillis();
GetRequest get = new GetRequest("http://" + "localhost:8180/crest2/v1/api?motionDeviceRelated=true&formatted=true");
get.send();
JSONObject json = parseJSONObject(get.getContent());
JSONObject motion = json.getJSONObject("motionAndDeviceRelated");
JSONArray acc = motion.getJSONArray("mWorldAcceleration");
x = acc.getFloat(0);
z = acc.getFloat(1);
y = acc.getFloat(2);
println(System.currentTimeMillis() - t);
loop();
}`

Related

how to write GameObject position in the Scene to json file?

on Clicking the button, I m loading the function WriteJsonForLevel(). I have placed three GameObject with the tag name "RedCoin" and I want to write the position of the GameObject to a JSON file. I can get the position of the object, but it's all overwritten. I can only see the last GameObject position (i.e the completion of the loop)
public List<GameObject> levelObjects;
public string level;
public Vector3 pos;
// Start is called before the first frame update
void Start()
{
levelObjects = new List<GameObject>();
}
// Update is called once per frame
void Update()
{
}
public void WritejsonForAll()
{
WriteJsonForLevel();
}
public void WriteJsonForLevel()
{
/* FileStream fs = new FileStream(Application.dataPath + "/sample.json",FileMode.Create);
StreamWriter writer= new StreamWriter(fs);*/
GameObject[] coinObjRed = GameObject.FindGameObjectsWithTag("RedCoin");
putAllObjectInList(coinObjRed);
}
public void putAllObjectInList(GameObject[] p)
{
string path = Application.dataPath + "/text.json";
foreach (GameObject q in p)
{
levelObjects.Add(q);
}
for (int i = 0; i < levelObjects.Count; i++)
{
GameObject lvlObj = levelObjects[i];
Vector3 pos = lvlObj.transform.position;
string posOutput = JsonUtility.ToJson(pos);
File.WriteAllText(path,posOutput);
Debug.Log("position:" + posOutput);
}
}
}
You are using WriteAllText which will overwrite the file every time it is called. As it is overwriting each time it is in the loop, it will only write the last object to the file as every other previous write is overwritten. I would consider making a serialized class of data, assigning the data to it, converting it to a JSON string then saving that.
// stores individual locations for saving
[System.Serializable]
public class IndividualLocation
{
public IndividualLocation(Vector3 pos)
{
xPos = pos.x;
yPos = pos.y;
zPos = pos.z;
}
public float xPos;
public float yPos;
public float zPos;
}
// stores all game locations for saving
[System.Serializable]
public class AllGameLocations
{
public List<IndividualLocation> Locations = new List<IndividualLocation>();
}
public void PutAllObjectInList(in GameObject[] p)
{
string path = Application.dataPath + "/text.json";
// create a new object to write to
AllGameLocations data = new AllGameLocations();
// iterate the objects adding each to our structure
foreach(GameObject obj in p)
{
data.Locations.Add(new IndividualLocation(obj.transform.position));
}
// now that the data is filled, write out to the file
File.WriteAllText(path, JsonUtility.ToJson(AllGameLocations));
}
If you need a snippet on how to load the data properly I can add one.
Edit: Here is a load snippet
public void LoadJSONObject()
{
string path = Application.dataPath + "/text.json";
// if the file path or name does not exist
if (!Directory.Exists(Path.GetDirectoryName(path)))
{
Debug.LogWarning("File or path does not exist! " + path);
return
}
// load in the save data as byte array
byte[] jsonDataAsBytes = null;
try
{
jsonDataAsBytes = File.ReadAllBytes(path);
Debug.Log("<color=green>Loaded all data from: </color>" + path);
}
catch (Exception e)
{
Debug.LogWarning("Failed to load data from: " + path);
Debug.LogWarning("Error: " + e.Message);
return;
}
if (jsonDataAsBytes == null)
return;
// convert the byte array to json
string jsonData;
// convert the byte array to json
jsonData = Encoding.ASCII.GetString(jsonDataAsBytes);
// convert to the specified object type
AllGameLocations returnedData;
JsonUtility.FromJsonOverwrite<AllGameLocations>(jsonData, AllGameLocations);
// use returnedData as a normal object now
float firstObjectX = returnedData.Locations[0].xPos;
}
}
Let me know if the Load works, just typed it up untested. Added some error handling as well to assure data exists and the load properly works.

JSONObject and Streams/Lambda

I'm trying to get more familiar with Java lambda, can do some streams and such but still a lot to learn.
Got this simple code using JSONObject and JSONArray (org.json.simple with this exact library and no other because Gson is too easy :P) is there a way to simplify the code with java lambda/streams? (I tried with no luck)
JSONArray jsonArray = (JSONArray) jsonObject.get("someData");
Iterator<JSONObject> iterator = jsonArray.iterator();
double total = 0;
while(iterator.hasNext()) {
JSONObject iteratedJson = iterator.next();
// iteratedJson.get("ip") = "101.99.99.101" example values
String ip = (String) iteratedJson.get("ip");
// Need only first octet
ip = ip.substring(0, ip.indexOf("."));
if (Integer.valueOf(ip) >= 1 && Integer.valueOf(ip) <= 100) {
// Another object inside the array object
JSONObject locationObject = (JSONObject) iteratedJson.get("location");
// Id is int but JSONObject don't let me parse int...
long locationId = (Long) locationObject.get("id");
if (locationId == 8) {
// iteratedJson.get("amount") = "$1,999.10" example values
Number number = NumberFormat.getCurrencyInstance(Locale.US).parse((String)iteratedJson.get("amount"));
// Don't need a lot of precission
total = total + number.doubleValue();
}
}
}
You can do like this:
first of all to extract data from JsonObject I've created a class. this class takes a JosonObject as an argument and extract its values as bellow.
class ExtractData {
Integer ip;
long id;
double amount;
public ExtractData(JSONObject jsonObject) {
this.ip = Integer.valueOf(jsonObject.get("ip").toString().split("\\.")[0]);
this.id = Long.parseLong(((JSONObject) jsonObject.get("location")).get("id").toString());
try {
this.amount = NumberFormat.getCurrencyInstance(Locale.US)
.parse((String) jsonObject.get("amount")).doubleValue();
} catch (ParseException e) {
this.amount = 0d;
}
}
// getter&setter
}
then you can use stream API to calculate the sum of the amount property.
jsonArray.stream()
.map(obj -> new ExtractData((JSONObject) obj))
.filter(predicate)
.mapToDouble(value -> ((ExtractData) value).getAmount())
.sum();
for simplifying I've extracted filter operation.
Predicate<ExtractData> predicate = extractData ->
extractData.getIp()>=1 && extractData.getIp()<=100 && extractData.getId() == 8;

Gson from Object To Object

I'm trying to do a json converter of a map with a generic Object.
assuming you have the following example:
class MyClass1
{
String v1;
Boolean v2;
}
class MyClass2
{
Integer v3;
String v4;
}
class MyContainer
{
Map<String, Object>lst;
MyContainer() {
lst = new HashMap<String, Object>();
}
}
public main() {
MyContainer c1, c2;
Gson g = new Gson();
c1 = new MyContainer();
MyClass1 my1 = new MyClass1();
MyClass2 my2 = new MyClass2();
my1.v1 = "v1";
my1.v2 = true;
my2.v3 = 10;
my2.v4="v4";
c1.lst.put("MyClass1", my1);
c1.lst.put("MyClass2", my2);
String json = g.toJson(c1);
c2 = g.fromJson(json, MyContainer.class);
When I use g.ToJson i have the good json result but, when i call g.fromJson it obviously doesn't convert well because it cannot understand which class must be use in order to map the input json.
Infact, the c2.lst.get("MyClass1") does not return an instance of MyClass1 but a com.google.gson.internal.StringMap

parse json for GWT SuggestBox

I want to parse a json response in Java and add its values to a suggestBox in GWT. It would be great if anyone can help me with a sample code.
["abc","def","ghi","jkl","mno","pqr","acb","dfe","gih","jlk","mon"]
public void parseResponse(String str){
MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
JSONValue jsonValue = JSONParser.parseLenient(str);
JSONArray jArray = jsonValue.isArray();
for(int i=0; i<jArray.size(); i++){
String companySymbol = jArray.get(i).isString().toString();
oracle.add(companySymbol);
}
}
You cannot use MultiWordSuggestOracle: you have to extend http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/SuggestOracle.html
(and its callback)
ex:
class MySuggestOrc extends SuggestOracle {
public void requestSuggestions(final SuggestOracle.Request request, final SuggestOracle.Callback callback) {
Receiver<YourJsonContainer> receiver = new Receiver<YourJsonContainer>() {
#Override
public void onSuccess(YourJsonContainer companiesJsonHolder) {
List<Suggestion> companies = //... the code to split json
SuggestOracle.Response response = new SuggestOracle.Response();
response.setSuggestions(companies)
callback.onSuggestionsReady( request, response );
}
}
AsyncRequest req = // get you json respons here and use ...
}
}

Java Reflection Problem

Hi I am currently doing my final year project; I need to develop an algorithm visualization tool. I need to cater for user-defined algo; that is animate the algorithm the user types in a text-editor provided in my tool.
I am using the Java Compiler API to compile the code that the user has typed and saved. My tool offers a set of classes that the user can use in his/her algo.
For example:
myArray(this class is provided by my tool)
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
public class myArray extends JComponent {
int size = 0;
int count = 0;
int[]hold;
Thread th;
public myArray(int[]arr)//pass user array as parameter
{
//th = new Thread();
size=arr.length;
hold = arr;//make a copy of the array so as to use later in swap operation
}
public int length()
{
return hold.length;
}
public void setAccessibleContext(AccessibleContext accessibleContext) {
this.accessibleContext = accessibleContext;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
this.setPreferredSize(new Dimension(360,100));
for(int i=1; i<=size; i++)
{
g2d.drawRect((i*30), 30, 30, 50);
}
for(int i=1; i<=size; i++)
{
g2d.drawString(Integer.toString(hold[i-1]), (i*30)+15, 30+25);
}
}
public void set(int i, int j)//position of the two elements to swap in the array
{
try {
th.sleep(2000);//sleep before swapping because else user won't see original array since it would swap and then sleep
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int temp = hold[i];
hold[i] = hold[j];
hold[j] = temp;
hold[i]=j;
this.repaint();//can use eapint with a class that extends JPanel
}
public void swap(int i, int j)//position of the two elements to swap in the array
{
try {
th.sleep(2000);//sleep before swapping because else user won't see original array since it would swap and then sleep
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int temp = hold[i];
hold[i] = hold[j];
hold[j] = temp;
this.repaint();//can use eapint with a class that extends JPanel
}
public int get(int pos)
{
return hold[pos];
}
}
This is a portion of my GUI that will cause the compilation:
JavaCompiler jc = null;
StandardJavaFileManager sjfm = null;
File javaFile = null;
String[] options = null;
File outputDir = null;
URL[] urls = null;
URLClassLoader ucl = null;
Class clazz = null;
Method method = null;
Object object = null;
try
{
jc = ToolProvider.getSystemJavaCompiler();
sjfm = jc.getStandardFileManager(null, null, null);
File[] files = new File[1];
//files[0] = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project/myArray.java");
//files[1] = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project/Tool.java");
files[0] = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project/userDefined.java");
// getJavaFileObjects’ param is a vararg
Iterable fileObjects = sjfm.getJavaFileObjects(files);
jc.getTask(null, sjfm, null, null, null, fileObjects).call();
// Add more compilation tasks
sjfm.close();
options = new String[]{"-d", "C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project"};
jc.getTask(null, sjfm, null, Arrays.asList(options), null, fileObjects).call();
outputDir = new File("C:/Users/user/Documents/NetBeansProjects/My_Final_Year_Project");
urls = new URL[]{outputDir.toURL()};
ucl = new URLClassLoader(urls);
clazz = ucl.loadClass("userDefined");
method = clazz.getMethod("user", null);
object = clazz.newInstance();
Object ob = method.invoke(object, null);
}
This is an example of a user-defined algo(userDefined.java):
import java.awt.*;
import javax.swing.*;
public class userDefined
{
public void user()
{
int [] numArr = {1,3,1,-1,5,-5,0,7,12,-36};
myArray myArray = new myArray(numArr);
JFrame frame = new JFrame("Rectangles");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(360, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.add(myArray);
for (int i=myArray.length(); i>1; i--)
{
for (int j=0; j<i-1; j++)
{
if (myArray.get(j) > myArray.get(j+1))
{
myArray.swap(j, j+1);
}
}
}
}
}
The problem I am getting is that if I try to use reflection like above; I only get a white window which does not show the animation) but just displays the result at the very end.
However if I use this instead of reflection(and change the method void user() to static void main(string args) in userDefined.java):
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if(compiler.run(null, null, null, "userDefined.java") != 0) {
System.err.println("Could not compile.");
System.exit(0);
}
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("java "+"userDefined");
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
it woks provided that after first compilation I place the myArray class in the same folder as the userDefined.java. In this case I can see the animation take place correctly.
How do I use reflection to invoke the main method instead of using an instance of the class.
Please I really need some help with this. Thanks!
You a violating / missusing the first rule of swing: acces swing components only in the EDT (Event Dispatch Thread).
When you start your program using the main method, you are violating that rule. This happens to work, but might have all kinds of weird effects. This is not a theoretic warning, it happend to me and it is not nice.
When you run it using reflection from your code, you are most likely in the EDT, so your algorithm runs completely before the GUI gets updated again (which also happens on the EDT). Thats why you see only the final result of the algorithm.
The correct way to do this would be:
Run the algorithm in a seperate thread and make sure all changes to your myArray Component happen in the EDT, using SwingUtilities.invokeAndWait or SwingUtilities.invokeLater