Format data to JSON like format - java

I'm using a charting library that needs that the input looks like some format. This format looks like JSON but it isn't, and here I share some data to get an idea about the format:
[{
year: 2005,
income: 23.5,
expenses: 18.1
}, {
year: 2006,
income: 26.2,
expenses: 22.8
}, {
year: 2007,
income: 30.1,
expenses: 23.9
}, {
year: 2008,
income: 29.5,
expenses: 25.1
}, {
year: 2009,
income: 24.6,
expenses: 25.0
}];
You can see the complete example in this link.
In my first test, I've used String.concat(anotherString) but I assure you that it's not comfortable. So is there any java API that provides this format?
Thanks in advance.

well, the only difference between that format and JSON looks like you just need to remove double quotes from the strings. So data.replaceAll("\"", ""); shall do the job.
but actually, reading the example, it shall accepts valid JSON. You shall try using a $.ajax() method, something that would look like :
AmCharts.ready(function () {$.ajax({
url: '/mydata/',
dataType: 'json',
data: undefined,
success: function(chartData) {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "year";
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.gridAlpha = 0.1;
categoryAxis.axisAlpha = 0;
categoryAxis.gridPosition = "start";
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.stackType = "regular";
valueAxis.gridAlpha = 0.1;
valueAxis.axisAlpha = 0;
chart.addValueAxis(valueAxis);
// GRAPHS
// first graph
var graph = new AmCharts.AmGraph();
graph.title = "Europe";
graph.labelText = "[[value]]";
graph.valueField = "europe";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#C72C95";
chart.addGraph(graph);
// second graph
graph = new AmCharts.AmGraph();
graph.title = "North America";
graph.labelText = "[[value]]";
graph.valueField = "namerica";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#D8E0BD";
chart.addGraph(graph);
// third graph
graph = new AmCharts.AmGraph();
graph.title = "Asia-Pacific";
graph.labelText = "[[value]]";
graph.valueField = "asia";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#B3DBD4";
chart.addGraph(graph);
// LEGEND
var legend = new AmCharts.AmLegend();
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
}
});
(sorry, I'm far from being good at writing javascript, but I think the idea is there). Also, maybe the API of amCharts enables you to direcly check a local URL. And then, you'll only have to route your JSON data as a REST call.

chk this API's data related blog page
http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-2.html
I think this tutorial tells about all the nitty gritties of handling the data in this API, with lots of examples and code snippets

the solution is simple:
var chartData = eval(json_data);
Best Regards

Related

protobuf-net serialize/deserialize DateTime & Guid types

I have some issue with getting values from TimeDate and Guid types from protobuf-net:
I have .Net Client and .Net Server and they are communicating via protobuf-net. And now I have to implement a communication from a java client to this .Net Server and I can not change already existed .Net Server communication logic so I have to use already existed protobuf communication and the issue is following:
protobuf-net understands two .net types: DateTime and Guid but I'm not able to parse it via google protobuf:
.Net Server class example:
[ProtoContract]
public class SomeClass
{
[ProtoMember(1)]
public DateTime? CurrentDateTime { get; set; }
[ProtoMember(2)]
public Guid CurrentGiud { get; set; }
}
I'm not able to parse it via google protobuf because it knows nothing about DateTime and Guid types so I can only get byte[] from these fields, .proto example:
message SomeClass
{
bytes CurrentDateTime = 1;
bytes CurrentGiud = 2;
}
So after serialization/deserialization a stream I can get byte[] from those fields and now I need somehow convert it to appropriate values, so I need something like this:
var customDateTime = ConvertByteArrayToCustomDateTime(byteArray);
byte[] byteArray = ConvertCustomDateTimeToByteArray(customDateTime);
var customGuid = ConvertByteArrayToCustomGuid(byteArray);
byte[] byteArray = ConvertCustomGuidToByteArray(customGuid);
or this:
string strDateTime = ConvertByteArrayToStringDateTime(byteArray); //e.g. "13.08.2019 17:42:31"
byte[] byteArray = ConvertStringDateTimeToByteArray(strDateTime);
string strGuid = ConvertByteArrayToStringGuid(byteArray); // e.g. "{7bb7cdac-ebad-4acf-90ff-a5525be3caac}"
byte[] byteArray = ConvertStringGuidToByteArray(strGuid);
DateTime real example:
Example N1:
DateTime = 13.08.2019 17:42:31
after serialization/deserialization
byte[] = { 8, 142, 218, 151, 213, 11, 16, 3 }
Example N2:
DateTime = 25.06.2019 20:15:10
after serialization/deserialization
byte[] = { 8, 156, 131, 148, 209, 11, 16, 3 }
Guid real example:
Example N1:
Guid = {7bb7cdac-ebad-4acf-90ff-a5525be3caac}
after serialization/deserialization
byte[] = { 9, 172, 205, 183, 123, 173, 235, 207, 74, 17, 144, 255, 165, 82, 91, 227, 202, 172 }
Example N2:
Guid = {900246bb-3a7b-44d4-9b2f-1da035ca51f4}
after serialization/deserialization
byte[] = { 9, 187, 70, 2, 144, 123, 58, 212, 68, 17, 155, 47, 29, 160, 53, 202, 81, 244 }
Solution:
Add following messages into your .proto:
message CustomDateTime
{
sint64 value = 1; // the offset (in units of the selected scale) from 1970/01/01
CustomTimeSpanScale scale = 2; // the scale of the timespan [default = DAYS]
CustomDateTimeKind kind = 3; // the kind of date/time being represented [default = UNSPECIFIED]
enum CustomTimeSpanScale
{
DAYS = 0;
HOURS = 1;
MINUTES = 2;
SECONDS = 3;
MILLISECONDS = 4;
TICKS = 5;
MINMAX = 15; // dubious
}
enum CustomDateTimeKind
{
// The time represented is not specified as either local time or Coordinated Universal Time (UTC).
UNSPECIFIED = 0;
// The time represented is UTC.
UTC = 1;
// The time represented is local time.
LOCAL = 2;
}
}
message CustomGuid
{
fixed64 lo = 1; // the first 8 bytes of the guid (note:crazy-endian)
fixed64 hi = 2; // the second 8 bytes of the guid (note:crazy-endian)
}
Now your .proto class should look like this:
message SomeClass
{
CustomDateTime CurrentDateTime = 1;
CustomGuid CurrentGiud = 2;
}
Simple DateTime parser:
public static string ConvertCustomDateTimeToString(CustomDateTime customDateTime)
{
var dateTime = DateTime.Parse("01.01.1970 00:00:00");
if (customDateTime.Scale == CustomDateTime.Types.CustomTimeSpanScale.Seconds)
{
dateTime = dateTime.AddSeconds(customDateTime.Value);
}
else
{
throw new Exception("CustomDateTime supports only seconds");
}
return dateTime.ToString();
}
public static CustomDateTime ConvertStringToCustomDateTime(string strDateTime)
{
var defaultTime = DateTime.Parse("01.01.1970 00:00:00");
var dateTime = DateTime.Parse(strDateTime);
var customDateTime = new CustomDateTime
{
Kind = CustomDateTime.Types.CustomDateTimeKind.Unspecified,
Scale = CustomDateTime.Types.CustomTimeSpanScale.Seconds,
Value = (long) (dateTime - defaultTime).TotalSeconds
};
return customDateTime;
}
Simple Guid parser:
public static string ConvertCustomGuidToString(CustomGuid customGuid)
{
var str = string.Empty;
var array = BitConverter.GetBytes(customGuid.Lo);
var newArray = new byte[8];
newArray[0] = array[3];
newArray[1] = array[2];
newArray[2] = array[1];
newArray[3] = array[0];
newArray[4] = array[5];
newArray[5] = array[4];
newArray[6] = array[7];
newArray[7] = array[6];
str += BitConverter.ToString(newArray).Replace("-", "");
str += BitConverter.ToString(BitConverter.GetBytes(customGuid.Hi)).Replace("-", "");
return str;
}
public static CustomGuid ConvertStringToCustomGuid(string strGuid)
{
strGuid = strGuid.Replace(" ", "");
strGuid = strGuid.Replace("-", "");
strGuid = strGuid.Replace("{", "");
strGuid = strGuid.Replace("}", "");
if (strGuid.Length != 32)
{
throw new Exception("Wrong Guid format");
}
byte[] array = new byte[16];
for (int i = 0; i < 32; i += 2)
array[i / 2] = Convert.ToByte(strGuid.Substring(i, 2), 16);
var newArrayLo = new byte[8];
newArrayLo[0] = array[3];
newArrayLo[1] = array[2];
newArrayLo[2] = array[1];
newArrayLo[3] = array[0];
newArrayLo[4] = array[5];
newArrayLo[5] = array[4];
newArrayLo[6] = array[7];
newArrayLo[7] = array[6];
var newArrayHi = new byte[8];
newArrayHi[0] = array[8];
newArrayHi[1] = array[9];
newArrayHi[2] = array[10];
newArrayHi[3] = array[11];
newArrayHi[4] = array[12];
newArrayHi[5] = array[13];
newArrayHi[6] = array[14];
newArrayHi[7] = array[15];
var customGuid = new CustomGuid
{
Lo = BitConverter.ToUInt64(newArrayLo, 0),
Hi = BitConverter.ToUInt64(newArrayHi, 0)
};
return customGuid;
}
We need to talk about the two types separately. There's back-story to each!
DateTime / TimeSpan - so: way back in history, .NET folks kept wanting protobuf-net to round-trip DateTime / TimeSpan. There was nothing defined by Google for this kind of purpose, so protobuf-net made something up. The details are in bcl.proto, but I don't recommend worrying about that. The short version would be: "they're kinda awkward to work with if you're not protobuf-net".
Roll forward 5+ years, and Google finally defined the well-known Duration and Timestamp types. Unfortunately, they're not 1:1 matches for how protobuf-net decided to implement them, and I can't change the default layout without breaking existing consumers. But! For new code, or for cross-platform purposes, protobuf-net knows how to talk Duration / Timestamp, and if it is even remotely possible, I strongly recommend changing your layout. The good news is: this is really simple:
[ProtoMember(1, DataFormat = DataFormat.WellKnown)]
public DateTime? CurrentDateTime { get; set; }
This will now use .google.protobuf.Timestamp instead of .bcl.DateTime; this also works with TimeSpan / .google.protobuf.Duration.
The key point here: there is a simple option that you can switch to that will make this "just work"; the default is for compatibility with something that protobuf-net had to invent before Google had decided on a layout.
Note that changing to DataFormat.WellKnown is a data breaking change; the layout is different. If there was a way to automatically detect and compensate, it already would; there isn't.
Guid - this should have been much simpler; the sensible idea here would have been to just to serialize it as bytes in .proto terms, but ... and I regret this, I did a stupid and tried to do something clever. It backfired and I regret it. What it does is ... kinda silly, although it does make sense internally. It accesses the Guid as two consecutive fixed64 fields (again, look in bcl.proto) where these are the low/high bytes in Microsoft's craz-endian layout. By crazy-endian, I mean where the guid 00112233-4455-6677-8899-AABBCCDDEEFF is represented by the bytes 33-22-11-00-55-44-77-66-88-99-AA-BB-CC-DD-EE-FF (emphasis: this bit isn't me; this is what Microsoft and .NET do internally with guids). So; to take your N1 example, the two half fragments you're seeing there are:
0x09 = "field 1, type fixed64"
0x AC-CD-B7-7B-AD-EB-CF-4A - first half in crazy-endian
0x11 (decimal 17) = "field 2, type fixed64"
0x 90-FF-A5-52-5B-E3-CA-AC - second half in crazy-endian
Frankly, for cross-platform work, I would suggest for Guid, expose it as string or byte[] instead, and accept my sincere apologies for the inconvenience!
In both cases: if you can't change the layout, look in bcl.proto for what is actually happening. If you use Serializer.GetProto<T>(), it should generate a schema that imports bcl.proto automatically.

Getting a Tensors value in Java

I habe trained a recurrent neural network with tensorflow using python. I saved the model and restored it in a Java-Application. This is working. Now i feed my input-Tensors to the pretrained modell and fetch the output. My problem now is, that the output is a Tensor and I don´t know hot to get the Tensors value (it is a simple integer-tensor of shape 1).
The python code looks like this:
sess = tf.InteractiveSession()
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs], name="input_x")
y = tf.placeholder(tf.int32, [ None])
keep_prob = tf.placeholder(tf.float32, name="keep_prob")
basic_cell = tf.contrib.rnn.OutputProjectionWrapper(tf.contrib.rnn.BasicRNNCell(num_units=n_neurons),output_size=n_outputs)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
logits = tf.layers.dense(states, n_outputs, name="logits")
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
loss = tf.reduce_mean(xentropy)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)
correct = tf.nn.in_top_k(logits, y,1, name="correct")
pred = tf.argmax(logits, 1, name="prediction")
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
init = tf.global_variables_initializer()
def train_and_save_rnn():
# create a Saver object as normal in Python to save your variables
saver = tf.train.Saver()
# Use a saver_def to get the "magic" strings to restore
saver_def = saver.as_saver_def()
print (saver_def.filename_tensor_name)
print (saver_def.restore_op_name)
# Loading the Train-DataSet
data_train, labels_train = load_training_data("Train.csv")
data_test, labels_test = load_training_data("Test.csv")
#labels_train=reshape_labels_to_sequences(labels_train)
#labels_test=reshape_labels_to_sequences(labels_test)
dt_train = reshape_data(data_train)
dt_test = reshape_data(data_test)
X_test = dt_test
X_test = X_test.reshape((-1, n_steps, n_inputs))
y_test = labels_test-1
sess.run(tf.global_variables_initializer())
# START TRAINING ...
for epoch in range(n_epochs):
for iteration in range(dt_train.shape[0]-1):
X_batch, y_batch = dt_train[iteration], labels_train[iteration]-1
X_batch = X_batch.reshape((-1, n_steps, n_inputs))
y_batch = y_batch.reshape((1))
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
acc_train = accuracy.eval(feed_dict={X: X_batch, y: y_batch})
acc_test = accuracy.eval(feed_dict={X: X_test, y: y_test})
print(epoch, "Train accuracy:", acc_train, "Test accuracy:", acc_test)
# SAVE THE TRAINED MODEL ...
builder.add_meta_graph_and_variables(sess, [tf.saved_model.tag_constants.SERVING])
builder.save(True) #true for human-readable
What I do in Java is:
byte[] graphDef = readAllBytesOrExit(Paths.get(IMPORT_DIRECTORY, "/saved_model.pbtxt"));
/*List<String> labels =
readAllLinesOrExit(Paths.get(IMPORT_DIRECTORY, "trained_model.txt"));
*/
try (SavedModelBundle b = SavedModelBundle.load(IMPORT_DIRECTORY, "serve")) {
// create the session from the Bundle
Session sess = b.session();
s = sess;
g = b.graph();
// This is just a sample Tensor for debugging:
Tensor t = Tensor.create(new float[][][] {{{(float)0.8231331,(float)-5.2657013,(float)-1.1111984,(float)0.0074825287,(float)0.075252056,(float)0.07835889,(float)-0.035752058,(float)-0.035610847,(float)0.045247793,(float)1.5594741,(float)57.78549,(float)-0.21489286,(float)0.011989355,(float)0.15965772,(float)13.370155,(float)3.4708557,(float)3.7776794,(float)-1.1115816,(float)0.72939104,(float)-0.44342846,(float)11.001129,(float)10.549805,(float)-50.719162,(float)-0.8261242,(float)0.71805984,(float)-0.1849739,(float)9.334606,(float)3.0003967,(float)-52.456577,(float)-0.1875816,(float)0.19306469,(float)0.004947722,(float)5.4054375,(float)-0.8630371,(float)-24.599575,(float)1.3387873,(float)-1.1488495,(float)-2.8362968,(float)22.174248,(float)-32.095154,(float)10.069847}}});
runTensor(t);
}
public static void runTensor(Tensor inputTensor) throws IOException, FileNotFoundException {
try (Graph graph = g;
Session sess = s;) {
Integer gesture = null;
Tensor y_ph = Tensor.create(new int[]{0});
Tensor result = sess.runner()
.feed("input_x", inputTensor)
.feed("Placeholder", y_ph)
.fetch("pred")
.run().get(0);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
The output should (I´m not sure if it´s working) be an Integer between 0 and 10 for the predicted class. How can I extract the Integer in Java from the Tensor?
Thank you in advance.
Use Tensor.intValue() if it is a scalar, or Tensor.copyTo() if it is not. (So System.out.println(result.intValue());)

Set custom column width size in google sheets

I'm using this Java code to generate Google sheets data from Java application.
List < RowData > rowDataValues = new ArrayList < > ();
List < CellData > headerValues = new ArrayList < > ();
headerValues.add(new CellData().setNote("ID")
.setUserEnteredValue(new ExtendedValue()
.setStringValue("#")).setUserEnteredFormat(myFormat));
.setStringValue("Environment")).setUserEnteredFormat(myFormat));
.........
headerValues.add(new CellData()
.setUserEnteredValue(new ExtendedValue()
.setStringValue("Name")).setUserEnteredFormat(myFormat));
RowData setHeaderValues = new RowData();
setHeaderValues.setValues(headerValues);
rowDataValues.add(setHeaderValues);
requests.add(new Request()
.setUpdateCells(new UpdateCellsRequest()
.setStart(new GridCoordinate()
.setSheetId(randomSheetId)
.setRowIndex(0)
.setColumnIndex(0))
.setRows(rowDataValues)
.setFields("*")));
BatchUpdateSpreadsheetRequest body = new BatchUpdateSpreadsheetRequest().setRequests(requests);
BatchUpdateSpreadsheetResponse response = service.spreadsheets().batchUpdate(spreadsheetId, body).execute();
How I can set custom width for each column?
Update:
This is what i've tried so far :
new UpdateDimensionPropertiesRequest().setRange(
new DimensionRange()
.setDimension("COLUMNS")
.setStartIndex(0).setEndIndex(1)
)
.setProperties(new DimensionProperties().setPixelSize(400)).setFields("pixelSize"));
You need to create UpdateDimensionPropertiesRequest. In your case you can use this sample code, which increases the size of first column (startIndex = 0, endIndex = 1) .
requests.add(new Request().setUpdateDimensionProperties(
new UpdateDimensionPropertiesRequest()
.setRange(
new DimensionRange()
.setSheetId(randomSheetId)
.setDimension("COLUMNS")
.setStartIndex(0)
.setEndIndex(1)
)
.setProperties(new DimensionProperties().setPixelSize(400)).setFields("pixelSize"))));
In here i used setDimension("COLUMNS") to change column(s) width, it is possible to change row(s) height by using setDimension("ROWS").
Additional problem from #PeterPenzov 's comment :
I get "Invalid requests.updateDimensionProperties: No grid with id: 0",
You'll get this error when your sheetId is not set properly.
From API v4 documentation SheetId is ;
Individual sheets in a spreadsheet have titles (which must be unique) and IDs. The sheetId is used frequently in the Sheets API to specify which sheet is being read or updated
So you need to set sheetId of DimensionRange Object. In your case you need to use your sheetId as randomSheetId(i've updated the code above).
Spreadsheet spreadsheet = service.spreadsheets().get(spreadsheetId).execute();
spreadsheet.getSheets().stream()
.map(s->s.getProperties().getSheetId())
.forEach(System.out::println);
Please take a look into dev documentation:
{
"requests": [
{
"updateDimensionProperties": {
"range": {
"sheetId": sheetId,
"dimension": "COLUMNS",
"startIndex": 0,
"endIndex": 1
},
"properties": {
"pixelSize": 160
},
"fields": "pixelSize"
}
}
]
}
Request body from the example for column width could be translated into the next Java code:
public void updateFirstColumnWidth(Sheets sheetService, String sheetId) throws IOException {
final Spreadsheet spreadsheet = sheetService.spreadsheets()
.get(sheetId)
.execute();
final var sheets = spreadsheet.getSheets();
final var sheet = sheets.get(0); // get your specific sheet
final int sheetUuid = sheet.getProperties().getSheetId();
final var batchRequest = new BatchUpdateSpreadsheetRequest();
List<Request> requests = List.of(getColumnWidthRequest(sheetUuid, 160));
batchRequest.setRequests(requests);
final BatchUpdateSpreadsheetResponse response = sheetService.spreadsheets()
.batchUpdate(sheetId, batchRequest)
.execute();
}
private Request getColumnWidthRequest(int sheetUuid, int width) {
return new Request()
.setUpdateDimensionProperties(
new UpdateDimensionPropertiesRequest()
.setRange(
new DimensionRange()
.setSheetId(sheetUuid)
.setDimension("COLUMNS")
.setStartIndex(0)
.setEndIndex(1)
)
.setProperties(new DimensionProperties().setPixelSize(width))
.setFields("pixelSize")
);
}

Search element in arraylist

How can I search element in arraylist and display it? Example is the user wants to search the code A25 Then it will print the whole content on that arraylist that he search only and the output is A25 CS 212 Data Structures 3.
Subject CS212 = new Subject("A25","\t\tCS 212","\t\tData Structures\t\t\t\t",units);
Subject IT312 = new Subject("A26","\t\tIT 312","\t\tData Base Management System 2\t\t",units);
Subject IT313 = new Subject("A27","\t\tIT 312","\t\tData Base Management System 2\t\t",units);
Subject CS313 = new Subject("A29","\t\tCS 313","\t\tDigital Designt\t\t\t\t",units);
Subject Disc = new Subject("A30","\t\tIT 212","\t\tDiscrete Structurest\t\t",units);
Subject A31 = new Subject("A31","\t\tIT 212","\t\tDiscrete Structurest\t\t",units);
Subject Engl3 = new Subject("984","\t\tEngl 3","\t\tSpeech and oral Communicationt\t\t",units);
Subject Theo3 = new Subject("582","\t\tTheo 3","\t\tChrist and Sacramentst\t\t",units);
Subject Stat = new Subject("470","\t\tStata1","\t\tProbablility and Statisticst\t\t",units);
Subject Dota = new Subject("999","\t\tDota 2","\t\tDota Guide\t\t\t\t",units);
ArrayList<Subject> arrList = new ArrayList<Subject>();
arrList.add(CS212);
arrList.add(IT312);
arrList.add(IT313);
arrList.add(CS313);
arrList.add(Disc);
arrList.add(A31);
arrList.add(Engl3);
arrList.add(Theo3);
arrList.add(Stat);
arrList.add(Dota);
//User input that he wants to search
for(int i = 0; i < 3; i++,num++)
{
System.out.print("\t\t"+num +". ");
codeNo[i] = scan.next();
String output = Character.toUpperCase(codeNo[i].charAt(0)) + codeNo[i].substring(1);
codeNo[i] = output;
}
// This is what I tried but it doesn't work Idk why
for (Subject s : arrList) {
for(int i =0; i < codeNo.length; i++)
if (s.equals(codeNo[i])) {
System.out.println("\t\t\t"+s);
}
}
public Subject(String codeNo, String subjectID, String title , int unit)
{
//Constructor . .
}
//Desired output
Code to search
A25
A26
A27
output
A25 CS 212 Data Structures 3
A26 IT 312 Data Base Management System 2 3
A27 IT 312 Data Base Management System 2 3
You are trying to search an arraylist of subjects, you need to write a small function to compare the code string to the corresponding string of the class. You can do this by adding this to your subject class.
Example :
#Override
public boolean equals(String code) {
return code.equals(this.<compare to member>);
}
and change the compare to member that needs to match the code that you match.
EDIT : Easier way to do is to just change your existing code to :
if (s.code.equals(codeNo[i])) //assuming your code class member is a public string

Android browser doesn't work with geolocation

I am building a website which use geolocation code, It suppose to load mapCanvas and after user click on "Finde Me!" button get his location and set a center of a map based on user location. It's working fine with Firefox, Chrome, Safari, tested on regular PC and iPhone the only device doesn't work with it is any mobile phone with Android. here is a code:
<script src="http://maps.google.com/maps?file=api&v=3&key=YourKey"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var iconBlue = new GIcon();
iconBlue.image = 'http://labs.google.com/ridefinder/images/mm_20_blue.png';
iconBlue.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
iconBlue.iconSize = new GSize(17, 25);
iconBlue.shadowSize = new GSize(1, 1);
iconBlue.iconAnchor = new GPoint(6, 20);
iconBlue.infoWindowAnchor = new GPoint(5, 1);
var iconRed = new GIcon();
iconRed.image = 'http://labs.google.com/ridefinder/images/mm_20_red.png';
iconRed.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
iconRed.iconSize = new GSize(17, 25);
iconRed.shadowSize = new GSize(1, 1);
iconRed.iconAnchor = new GPoint(6, 20);
iconRed.infoWindowAnchor = new GPoint(5, 1);
var customIcons = [];
customIcons["restaurant"] = iconBlue;
customIcons["bar"] = iconRed;
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(50.061795,19.936924), 16);
// Change this depending on the name of your PHP file
GDownloadUrl("Your_xml.php", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = createMarker(point, name, address, type);
map.addOverlay(marker);
}
});
}
}
function createMarker(point, name, address, type) {
var marker = new GMarker(point, customIcons[type]);
var html = "<b>" + name + "</b> <br/>" + address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
//]]>
function findLoc(){
if (!navigator.geolocation) {
alert('Sorry, your browser does not support Geo Services');
}
else {
// Get the current location
navigator.geolocation.getCurrentPosition(showMap);
}
}
function showMap(position){
var lat = position.coords.latitude;
var lon = position.coords.longitude;
var myPoint = new GLatLng(lat, lon);
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(myPoint, 15);
GDownloadUrl("Your_xml.php", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = createMarker(point, name, address, type);
map.addOverlay(marker);
}
});
function createMarker(point, name, address, type) {
var marker = new GMarker(point, customIcons[type]);
var html = "<b>" + name + "</b> <br/>" + address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
}
I couldn't find any solution to make it work.
PS
There is no errors or statements giving any hint making it more understandable.
Device got GPS enable.
pleas help I've been trying to figure it out for 2 weeks
I'm afraid you just have an arduous old-fashioned debug in front of you. My approach would be to add visible output at various important points in the code (just before and after getCurrentPosition is called, and at the beginning of showMap, for instance) and narrow down from there just where the failure is occurring. Once you know what's failing you can probably develop an idea of why, but until you know that you're flailing in the dark.
(I've worked on a geolocation-based mobile webapp that supported Android, so in case you need any reassurance, there's nothing inherently impossible about your situation.)

Categories

Resources