I have a spatial db with links,nodes,traffic restriction etc..
I want to convert those spatial data to osm.pbf ,I know some osm.pbf
from https://wiki.openstreetmap.org/wiki/PBF_Format
structrue,like Node ,Way,Relation.
message Node {
required sint64 id = 1;
// Parallel arrays.
repeated uint32 keys = 2 [packed = true]; // String IDs.
repeated uint32 vals = 3 [packed = true]; // String IDs.
optional Info info = 4; // May be omitted in omitmeta
required sint64 lat = 8;
required sint64 lon = 9;
}
I use java and pfb tool convert the message to java class,then I create pdf file.
Where is the ChangeSet message I can't find it anywhere.
Related
I have to read and write some values to a Bike Smart trainer with BLE (Bluetooth Low Energy) used with Flutter. When I try to read the values from the GATT characteristic org.bluetooth.characteristic.supported_power_range (found on bluetooth.org site https://www.bluetooth.com/specifications/gatt/characteristics/ ) I get the return value of an Int List [0,0,200,0,1,0].
The GATT characteristic sais that there are 3 sint16 fields for Min., Max. and step size Watts (Power).
The Byte transmission order also sais that the least significant octet is transmitted first.
My guessings are, that the 3 parameters are returned in an Int array with 8bit value each. But I can't interpret the 200 for maybe the maximum Power setting. Because the smart trainer should provide max. 2300W Watts resistance (ELITE Drivo https://www.elite-it.com/de/produkte/home-trainer/rollentrainer-interaktive/drivo)
The Output results from this code snippet:
device.readCharacteristic(savedCharacteristics[Characteristics.SUPPORTED_POWER_RANGE]).then((List<int> result) {
result.forEach((i) {
print(i.toString());
});
});
// result: [0,0,200,0,1,0]
Maybe some one of u knows how to interpret the binary/hex/dec values of the flutter_blue characteristic output.
Or some hints would be great
Edit
For future readers, I got the solution. I'm a bit asheamed because I read the wrong characteristic.
The return value [0,0,200,0,1,0] was for supported resistance level. (which is 20% and the 200 shows the 20% with a resolution of 0.1 like described in the GATT spec)
I also got a return value for the supported power level which was [0,0,160,15,1,0]. Now the solution how to read the 2 Bytes of max powre level: you get the 160,15 the spec sais LSO (least significant octet first, don't confuse it with LSB least significant bit first). In fact of that you have to read it like 15,160. now do the math with the first Byte 15*256 + 160 = 4000 and thats the correct maximum supported power of the trainer like in the datasheet.
I hope I help someone with that. Thanks for the two replys they are also correct and helped me to find my mistake.
I had the same problem connecting to a Polar H10 to recover HR and RR intervals. It might not be 100% the same, but I think my case can guide you to solve yours.
I am receiving the same list as you like these two examples:
[0,60]
[16,61,524,2]
Looking at the specs of the GATT Bluetooth Heart Rate Service I figured that each element of the list retrieved matches 1 byte of the data transmitted by the characteristic you are subscripted to. For this service, the first byte, i.e., the first element of the list, has some flags to point out if there is an RR value after the HR value (16) or not (0). This is just two cases among the many different ones that can ocur depending on the flags values, but I think it shows how important this first byte can be.
After that, the HR value is coded as an unsigned integer with 8 bits (UINT8), that is, the HR values match the second element of the lists shown before. However, the RR interval is coded as an unsigned integer eith 16bits (UINT16), so it complicates the translation of those two last elements of the list #2 [16,61,524,2], because we should use 16 bits to get this value and the bytes are not in the correct order.
This is when we import the library dart:typed_data
import 'dart:typed_data';
...
_parseHr(List<int> value) {
// First sort the values in the list to interpret correctly the bytes
List<int> valueSorted = [];
valueSorted.insert(0, value[0]);
valueSorted.insert(1, value[1]);
for (var i=0; i< (value.length-3); i++) {
valueSorted.insert(i+2, value[i+3]);
valueSorted.insert(i+3, value[i+2]);
}
// Get flags directly from list
var flags = valueSorted[0];
// Get the ByteBuffer view of the data to recode it later
var buffer = new Uint8List.fromList(valueSorted).buffer; // Buffer bytes from list
if (flags == 0) {
// HR
var hrBuffer = new ByteData.view(buffer, 1, 1); // Get second byte
var hr = hrBuffer.getUint8(0); // Recode as UINT8
print(hr);
}
if (flags == 16) {
// HR
var hrBuffer = new ByteData.view(buffer, 1, 1); // Get second byte
var hr = hrBuffer.getUint8(0); // Recode as UINT8
// RR (more than one can be retrieved in the list)
var nRr = (valueSorted.length-2)/2; // Remove flags and hr from byte count; then split in two since RR is coded as UINT16
List<int> rrs = [];
for (var i = 0; i < nRr; i++) {
var rrBuffer = new ByteData.view(buffer, 2+(i*2), 2); // Get pairs of bytes counting since the 3rd byte
var rr = rrBuffer.getUint16(0); // Recode as UINT16
rrs.insert(i,rr);
}
print(rrs);
}
Hope it helps, the key is to get the buffer view of the sorted list, get the bytes that you need, and recode them as the standard points out.
I used print(new String.fromCharCodes(value)); and that worked for me.
value is your return from List<int> value = await characteristic.read();
I thank ukBaz for his answer to this question. Write data to BLE device and read its response flutter?
You can use my package byte_data_wrapper to transform this data to a decimal value which you can understand:
Get the buffer:
import 'dart:typed_data';
final buffer = Uint16List.fromList(result).buffer;
Create the byteDataCreator:
// Don't forget to add it to your pubspec.yaml
//dependencies:
// byte_data_wrapper:
// git: git://github.com/Taym95/byte_data_wrapper.git
import 'byte_data_wrapper/byte_data_wrapper.dart';
final byteDataCreator = ByteDataCreator.view(buffer);
Get your data :
// You can use getUint8() if valeu is Uint8
final min = byteDataCreator.getUint16();
final max = byteDataCreator.getUint16();
final stepSize = byteDataCreator.getUint16();
I know its too late to answer this but if there is anyone still having a trouble, just convert it manually to be an integer. Because I think you are receiving a type of ByteArray (correct me if I'm wrong).
num bytesToInteger(List<int> bytes) {
/// Given
/// 232 3 0 0
/// Endian.little representation:
/// To binary
/// 00000000 00000000 00000011 11101000
/// Combine
/// 00000000000000000000001111101000
/// Equivalent : 1000
num value = 0;
//Forcing to be Endian.little (I think most devices nowadays uses this type)
if (Endian.host == Endian.big) {
bytes = List.from(bytes.reversed);
}
for (var i = 0, length = bytes.length; i < length; i++) {
value += bytes[i] * pow(256, i);
}
return value;
}
and vice versa when you try to write over 255
Uint8List integerToBytes(int value) {
const arrayLength = 4;
return Uint8List(arrayLength)..buffer.asByteData().setInt32(0, value, Endian.little);
}
Hope this helps.
P.S. I also posted the similar problem here.
I try to read the values from a cell as a String (as one would see it in Excel). I reads from a xlsx (XSSFWorkbook) using Apache POI 3.15.
My goal is e.g. to omit decimal point and trailing zeros if the cell contains an integer. This works for CellType.NUMERIC:
val dataFormatter = new DataFormatter(true) // set emulateCsv to true
val stringValue = dataFormatter.formatCellValue(cell)
If I use the same code for CellType.FORMULA cell (e.g. a cell which references another "integer" cell), it just gives me the formula as a string instead of its computed value.
How can I get value of the formula-cell as displayed in Excel displays?
You need to "evaluate" cells in order to get the result of formulas. This is not done automatically by POI as it can be a heavy operation and often will not be necessary.
See http://poi.apache.org/spreadsheet/eval.html for details, basically you create a FormulaEvaluator and retrieve a CellValue for the Cell in question
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
...
CellValue cellValue = evaluator.evaluate(cell);
Thanks to Centic and Raphael I ended up using the concept with NumberFormat to fix an issue, this is Java but I am sure it can easily be converted to Scala
The issue is around numbers with decimal places which produces scientific decimal points.
This was only required when converting Apache POI XLS / XLSX to CSV format
//Create an evaluator from current work book
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
// Cell cell2 = evaluator.evaluateInCell(cell);
// As per above get CellValue
CellValue cellValue = evaluator.evaluate(cell);
//Get Double Value of formula which may contain E numbers
Double value = cellValue.getNumberValue();
// This gets numberFormat (below function) and assigns correct formatting to it
NumberFormat formatter = getNumberFormat(value);
//This should now be string value of number with correct decimal place values (non scientific)
formatter.format(value)
/**
* getNumberFormat takes number and either assigns #0
* if no decimal places or
* depending on how many numbers after decimal place assigns correct format
*/
public static NumberFormat getNumberFormat(Double value) {
String v = value.toString();
String format = "#0";
// This fixes scientific value issue
if (v.contains(".")) {
int decimals = v).substring(v.indexOf(".") + 1).length();
//Calls generateNumberSigns based on decimal places in given double
String numberSigns = generateNumberSigns(decimals);
format = "0." + numberSigns;
}
return new DecimalFormat(format);
}
/**
* This will generate correct formula for amount of decimal places
*/
public static String generateNumberSigns(int n) {
String s = "";
for (int i = 0; i < n; i++) {
s += "#";
}
return s;
}
My metadata is stored in a 8 bit unsigned dataset in a HDF5 file. After importing to DM, it become a 2D image of 1*length dimension. Each "pixel" stores the ASCII value of the corresponding value to the character.
For further processing, I have to convert the ASCII array to a single string, and further to TagGroup. Here is the stupid method (pixel by pixel) I currently do:
String Img2Str (image img){
Number dim1, dim2
img.getsize(dim1,dim2)
string out = ""
for (number i=0; i<dim1*dim2; i++)
out += img.getpixel(0,i).chr()
Return out
}
This pixel-wise operation is really quite slow! Is there any other faster method to do this work?
Yes, there is a better way. You really want to look into the chapter of raw-data streaming:
If you hold raw data in a "stream" object, you can read and write it in any form you like. So the solution to your problem is to
Create a stream
Add the "image" to the stream (writing binary data)
Reset the steam position to the start
Read out the binary data a string
This is the code:
{
number sx = 10
number sy = 10
image textImg := IntegerImage( "Text", 1, 0 , sx, sy )
textImg = 97 + random()*26
textImg.showimage()
object stream = NewStreamFromBuffer( 0 )
ImageWriteImageDataToStream( textImg, stream, 0 )
stream.StreamSetPos(0,0)
string asString = StreamReadAsText( stream, 0, sx*sy )
Result("\n as string:\n\t"+asString)
}
Note that you could create a stream linked to file on disc and, provided you know the starting position in bytes, read from the file directly as well.
Here's a real-life example; hand-written .proto file extract:
message StatsResponse {
optional int64 gets = 1;
optional int64 cache_hits = 12;
optional int64 fills = 2;
optional uint64 total_alloc = 3;
optional CacheStats main_cache = 4;
optional CacheStats hot_cache = 5;
optional int64 server_in = 6;
optional int64 loads = 8;
optional int64 peer_loads = 9;
optional int64 peer_errors = 10;
optional int64 local_loads = 11;
}
I understand everything about it except how the programmer who wrote it chose the tag numbers he was going to use.
The official documentation just notes how these tags are shifted around and encoded to compose a wire type identifier. Yet, in the example above, several fields of the same data type have different tag numbers.
My question is; how do I choose tag numbers if I was going to write a .proto file from scratch?
The number is just an alternative way to identify the field, other than its name. The encoding uses numbers rather than names because they take less space and time to encode. It doesn't matter what number you use as long as you don't change the number later (although, lower numbers take less space on the wire).
Usually, people simply assign numbers sequentially starting from 1. In your example proto, cache_hits is probably a new field that was added after all the others, which is why its number appears "out-of-order".
I have an NSMutableDictionary that possibly contains more than twenty objects.
If it contains more than 20 objects, how should I remove the oldest entries until there is only 20 left?
For example, NSMutableDictionary with objects:
a = "-1640531535";
b = 1013904226;
c = "-626627309";
d = 2027808452;
e = 387276917;
f = "-1253254618";
g = 1401181143;
h = "-239350392";
i = "-1879881927";
With max number of objects: 5, should become:
a = "-1640531535";
b = 1013904226;
c = "-626627309";
d = 2027808452;
e = 387276917;
Thank you.
If all you're looking for is 20 elements, I'd try something like:
NSMutableDictionary* newDict = [NSMutableDictionary new];
int count = 0;
for (id theKey in oldDict)
{
[newDict setObject:[oldDict getObjectForKey:theKey] forKey:theKey];
if (++count == 20)
break;
}
[oldDict release];
oldDict = newDict;
The idea being that you copy the elements of the first 20 keys you find into a new dictionary, then replace the old one with the new one. If you want to iterate the dictionary via other means you could do that too, but the code above wouldn't have to change much.
If the keys are NSNumbers and you know they're sequential, and you want to remove the lower values, then:
int limit=20; //set to whatever you want
int excess = limit - [dict count];
if (excess > 0) {
for (int i = 1; i <= excess; i++) {
[dict removeObjectForKey:[NSNumber numberWithInt:i]];
}
}
If your keys are NSStrings then just create the NSString with the corresponding format.
If your keys are not sequential, then you would have to either have a parallel dictionary with the date of storage for each entry, so you would know when each entry was stored and you can remove the oldest, or you need to use something else entirely (if you are storing sequential integers as keys, wouldn't it be easier to use NSMutableArray?)