how to get real direction steps using Flutter? (draw real route) - google-maps

I'm working with taxi app. Is it possible to draw real route on real road using flutter?
I used this way: https://developers.google.com/maps/documentation/directions/intro#ExampleRequests
getDirectionSteps(double destinationLat, double destinationLng) {
network
.get("origin=" +
location.latitude.toString() +
"," +
location.longitude.toString() +
"&destination=" +
destinationLat.toString() +
"," +
destinationLng.toString() +
"&key=api_key")
.then((dynamic res) {
List<Steps> rr = res;
print(res.toString());
ccc = new List();
for (final i in rr) {
ccc.add(i.startLocation);
ccc.add(i.endLocation);
}
mapView.onMapReady.listen((_) {
mapView.setMarkers(getMarker(location.latitude,location.longitude,destinationLat,destinationLng));
mapView.addPolyline(new Polyline("12", ccc, width: 15.0));
});
_screenListener.dismissLoader();
showMap();
}).catchError((Exception error) => _screenListener.dismissLoader());
}
my output look like this:
But I need like this: (draw destination route on real road)

to find the exact route you have to get points out of the polylineoverview from the json from directions api.
This is how I extracted the exact route just like you show in the second image.
Its is a function that return points as a string
Future<String> getRouteCoordinates(LatLng l1, LatLng l2) async {
String url =
"https://maps.googleapis.com/maps/api/directions/json?origin=${l1.latitude},${l1.longitude}&destination=${l2.latitude},${l2.longitude}&key=${Constants.anotherApiKey}";
http.Response response = await http.get(url);
Map values = jsonDecode(response.body);
ProjectLog.logIt(TAG, "Predictions", values.toString());
return values["routes"][0]["overview_polyline"]["points"];
}
you will get a string of points somewhat similiar to this
u|umDs`gwML}A_GGgFGAWwDEm#TcFGsAAa#BeA\QDe#AYISOKHKJGFw#^?jAAnAEnOA|GAhHEx#?jA#tC?XFLLf#Bf##t#?xAA|E?dEEj_#GxMChG#tCIvl##tAK`DQlA?zBApE?lBExNAlH#rMAtGJdDJnATfB`AnEdAzEj#~B|#lEF\xAvGnAlF~#lEv#`DvAxFxAxGzCdN`H`ZnEnRr#hDnB|IhDlNvKnd#vDhPrFzUzGjYxBtH|#hCdAzBXl#fAhBtAtBjBhCfArAdAhAvBtBlB|AjGfFhLzJfEzDzCvDz#pA`BpC`ApBbAzBxCrIr#rBjNta#x#nBbAlBzCbI|R|j#hA`FBVC`ASpD?lA[FiMpCaBVgABiAPoE~#cIdBiLfCcHdBsCl#yJvBmDt#y#l#{#X_#P[VGJGZCd#r#tCf#rBTbAV`BB`#?n#GdA#XHj#bAxBl#hBPjADf#?v#Ej#Ml#Ut#[r#]h#sA`C{#lAMZGl#KjECbDGhBuGMsJKcCGw#CqJCiECAd#ALoBbKs#jDM^x#j#vPfLvCnB~DnCx#f#R#RAd#GDIbBmDv#y#LId#On#A~EJX#pDJrADb#QFC
Now you will add the polyline in the set of polylines like this
_polyLines.add(Polyline(
polylineId: PolylineId(Constants.currentRoutePolylineId),//pass any string here
width: 3,
geodesic: true,
points: Utils.convertToLatLng(Utils.decodePoly(encodedPoly)),
color: ConstantColors.PrimaryColor));
here encodedPoly is the same string that extracted from previous method.
In the function above you have to convert the points\encodedPoly into the list of latlng. Like i did using utils function.
Both functions that i used are
decodePoly :
// !DECODE POLY
static List decodePoly(String poly) {
var list = poly.codeUnits;
var lList = new List();
int index = 0;
int len = poly.length;
int c = 0;
// repeating until all attributes are decoded
do {
var shift = 0;
int result = 0;
// for decoding value of one attribute
do {
c = list[index] - 63;
result |= (c & 0x1F) << (shift * 5);
index++;
shift++;
} while (c >= 32);
/* if value is negative then bitwise not the value */
if (result & 1 == 1) {
result = ~result;
}
var result1 = (result >> 1) * 0.00001;
lList.add(result1);
} while (index < len);
/*adding to previous value as done in encoding */
for (var i = 2; i < lList.length; i++) lList[i] += lList[i - 2];
print(lList.toString());
return lList;
}
and convertToLatLng() :
static List<LatLng> convertToLatLng(List points) {
List<LatLng> result = <LatLng>[];
for (int i = 0; i < points.length; i++) {
if (i % 2 != 0) {
result.add(LatLng(points[i - 1], points[i]));
}
}
return result;
}
This would make a exact route like i did in my app :
Here is the screenshot :

Related

Refer to json individual objects in cpp crow

i am using a cpp crow library and i am having difficulty in accessing individual objects i am attaching my code here.
CROW_ROUTE(app,"/hello/<string>")
([](string name){
crow::json::wvalue x;
x["name"] = "llllds";
x["Town"] = "Texas";
x["nickname"] = "drax";
x["father"] = "Nethan";
if (name == "Nothing")
cout << "Bad Responce";
std::ostringstream os;
cout << name << " is the required query";
val = x[name];
return val;
And i want to return my name can anyone help me with this. Thanks in advance
I used JSON for Modern C++ within crow (https://github.com/nlohmann/json)
Here is an example CROW_ROUTE I wrote
CROW_ROUTE(app, "/palindromes/<string>/<string>")([](const request &req, response &res, string ID, string words){
palindromeHash.insert({ID, words}); //ignore this
nlohmann::json x;
x = getPalindromes(palindromeHash.at(ID));
palindromeHash.erase(ID); //ignore this
res.sendJSON(x);
});
//getPalindromesFunction()
nlohmann::json getPalindromes(string data){
nlohmann::json x;
unordered_map<string, bool> hashmap;
string word = "";
std::string::size_type i = data.find("%20");
while (i != std::string::npos){
data.erase(i, 3);
data.insert(i, " ");
i = data.find("%20", i);
}
for(int i = 0; i < data.size(); i++){
if(data[i] == ' '){
hashmap.insert({word, true});
word = "";
}
else{
word += data[i];
}
}
string temp;
vector<string> words;
int numValid = 0;
for(auto& i: hashmap){
temp = i.first;
reverse(temp.begin(), temp.end());
auto got = hashmap.find(temp);
if(got != hashmap.end()){
words.push_back(i.first);
numValid++;
}
}
x["words"] = words;
x["numValid"] = numValid;
return x;
}
As you can see it returns a JSON object x that holds palindromes. The sendJSON() function is something I added to crow_all.h. Add it under the struct response section on line 7215
void sendJSON(const nlohmann::json& data){
std::string response = data.dump();
add_header("Access-Control-Allow-Origin", "*");
add_header("Content-Type", "text/html");
write(response);
end();
}
Remember to include "json.h" in both main.cpp and crow_all.h. The res.sendJSON will send it to my JS file which can loop through the JSON with ease.
$.get("/palindromes/" + ID + "/" + curr_line, {}, function(response){
let x = JSON.parse(response); //This will allow JS to read the C++ JSON
for(let i = 0; i < x.words.length; i++){
term.write(x.words[i] + "\r\n");
}
}

Export html to Excel format? [duplicate]

I want to extract some data like " email addresses " .. from table which are in PDF file and use this email addresses which I extract to send email to those people.
What I have found so far through searching the web:
I have to convert the PDF file to Excel to read the data easily and use them as I want.
I find some free dll like itextsharp or PDFsharp.
But I didn't find any snippet code help to do this in C#. is there any solution ?
You absolutely do not have to convert PDF to Excel.
First of all, please determine whether your PDF contains textual data, or it is scanned image.
If it contains textual data, then you are right about using "some free dll". I recommend iTextSharp as it is popular and easy to use.
Now the controversial part. If you don't need rock solid solution, it would be easiest to read all PDF to a string and then retrieve emails using regular expression.
Here is example (not perfect) of reading PDF with iTextSharp and extracting emails:
public string PdfToString(string fileName)
{
var sb = new StringBuilder();
var reader = new PdfReader(fileName);
for (int page = 1; page <= reader.NumberOfPages; page++)
{
var strategy = new SimpleTextExtractionStrategy();
string text = PdfTextExtractor.GetTextFromPage(reader, page, strategy);
text = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(text)));
sb.Append(text);
}
reader.Close();
return sb.ToString();
}
//adjust expression as needed
Regex emailRegex = new Regex("Email Address (?<email>.+?) Passport No");
public IEnumerable<string> ExtractEmails(string content)
{
var matches = emailRegex.Matches(content);
foreach (Match m in matches)
{
yield return m.Groups["email"].Value;
}
}
Using bytescout PDF Extractor SDK we can be able to extract the whole page to csv as below.
CSVExtractor extractor = new CSVExtractor();
extractor.RegistrationName = "demo";
extractor.RegistrationKey = "demo";
TableDetector tdetector = new TableDetector();
tdetector.RegistrationKey = "demo";
tdetector.RegistrationName = "demo";
// Load the document
extractor.LoadDocumentFromFile("C:\\sample.pdf");
tdetector.LoadDocumentFromFile("C:\\sample.pdf");
int pageCount = tdetector.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
int j = 1;
do
{
extractor.SetExtractionArea(tdetector.GetPageRect_Left(i),
tdetector.GetPageRect_Top(i),
tdetector.GetPageRect_Width(i),
tdetector.GetPageRect_Height(i)
);
// and finally save the table into CSV file
extractor.SavePageCSVToFile(i, "C:\\page-" + i + "-table-" + j + ".csv");
j++;
} while (tdetector.FindNextTable()); // search next table
}
public void Convert(string fileNames) {
int pageCount = 0;
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(fileNames);
pageCount = reader.NumberOfPages;
string ext = System.IO.Path.GetExtension(fileNames);
//string[] outfiles = new string[pageCount];
//Excel.Application app = new Excel.Application();
//app.Workbooks.Add("");
CSVExtractor extractor = new CSVExtractor();
//string outfilePDF1 = fileNames.Replace((System.IO.Path.GetFileName(fileNames)), (System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_rez" + ".csv"));
string outfilePDFExcel1 = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
(System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_rez" + ".xls"));
extractor.RegistrationName = "demo";
extractor.RegistrationKey = "demo";
string folderName = #"C:\Users\Dafina\Desktop\PDF_EditProject\PDF_EditProject\PDFs";
string pathString = System.IO.Path.Combine(folderName, System.IO.Path.GetFileName(fileNames).Replace(".pdf", "")) + "-CSVs";
System.IO.Directory.CreateDirectory(pathString);
for (int i = 0; i < pageCount; i++)
{
string outfilePDF = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
(System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_" + (i + 1).ToString()) + ext);
extractor.LoadDocumentFromFile(outfilePDF);
//string outfile = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
// (System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_" + (i + 1).ToString()) + ".csv");
string outfile = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
(System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "-CSVs\\" + "Sheet_" + (i + 1).ToString()) + ".csv");
extractor.SaveCSVToFile(outfile);
}
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
Console.WriteLine("Excel is not properly installed!!");
return;
}
Excel.Workbook xlWorkBook;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
string[] cvsFiles = Directory.GetFiles(pathString);
Array.Sort(cvsFiles, new AlphanumComparatorFast());
//string[] lista = new string[pageCount];
//for (int t = 0; t < pageCount; t++)
//{
// lista[t] = cvsFiles[t];
//}
//Array.Sort(lista, new AlphanumComparatorFast());
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
for (int i = 0; i < cvsFiles.Length; i++)
{
int sheet = i + 1;
xlWorkSheet = xlWorkBook.Sheets[sheet];
if (i < cvsFiles.Length - 1)
{
xlWorkBook.Worksheets.Add(Type.Missing, xlWorkSheet, Type.Missing, Type.Missing);
}
int sheetRow = 1;
Encoding objEncoding = Encoding.Default;
StreamReader readerd = new StreamReader(File.OpenRead(cvsFiles[i]));
int ColumLength = 0;
while (!readerd.EndOfStream)
{
string line = readerd.ReadLine();
Console.WriteLine(line);
try
{
string[] columns = line.Split((new char[] { '\"' }));
for (int col = 0; col < columns.Length; col++)
{
if (ColumLength < columns.Length)
{
ColumLength = columns.Length;
}
if (col % 2 == 0)
{
}
else if (columns[col] == "")
{
}
else
{
xlWorkSheet.Cells[sheetRow, col + 1] = columns[col].Replace("\"", "");
}
}
sheetRow++;
}
catch (Exception e)
{
string msg = e.Message;
}
}
int k = 1;
for (int s = 1; s <= ColumLength; s++)
{
xlWorkSheet.Columns[k].Delete();
k++;
}
releaseObject(xlWorkSheet);
readerd.Close();
}
xlWorkBook.SaveAs(outfilePDFExcel1, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,
misValue, misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive,
misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkBook);
releaseObject(xlApp);
var dir = new DirectoryInfo(pathString);
dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly;
dir.Delete(true);
}
Probably the Best code would be to use Third party dll
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
string pathToPdf = #"D:\abc\abc.pdf";
string pathToExcel = Path.ChangeExtension(pathToPdf, ".xls");
SautinSoft.PdfFocus f = new SautinSoft.PdfFocus();
f.ExcelOptions.ConvertNonTabularDataToSpreadsheet = false;
// 'true' = Preserve original page layout.
// 'false' = Place tables before text.
f.ExcelOptions.PreservePageLayout = true;
// The information includes the names for the culture, the writing system,
// the calendar used, the sort order of strings, and formatting for dates and numbers.
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-US");
ci.NumberFormat.NumberDecimalSeparator = ",";
ci.NumberFormat.NumberGroupSeparator = ".";
f.ExcelOptions.CultureInfo = ci;
f.OpenPdf(pathToPdf);
if (f.PageCount > 0)
{
int result = f.ToExcel(pathToExcel);
// Open the resulted Excel workbook.
if (result == 0)
{
System.Diagnostics.Process.Start(pathToExcel);
}
}
}
}
}

Google Elevation API - splitting multiple elevation requests

I'm trying to split a big request for elevation into multiple requests to avoid the 1sec/request and 512 coords limit in each request.
The problem I face is that the reply of my requests are not always received in the good order. Is using setInterval reliable enough?
Here is an example of response received in the wrong order that cause a problem (before using setInterval):
https://www.dropbox.com/s/x00jdnprj6w7lga/correctMap.png?dl=0
Here is my latest code:
function getCourseElevationData() {
var path = bikePathCoordinates; //Bunch of lat,long coords
// numberRequestToDo = Math.ceil(path.length/512); //TODO: split request in multiple 512 pack (google quotas)
numberRequestToDo = 2; //Temporary for testing
currentRequestNumber = -1; //will be at 0 on first call to get512Elevation
arrayOfRequest = [];
//1
var ptrStart= 0;
var pathSliced = path.slice(ptrStart, ptrStart+512);
arrayOfRequest.push(pathSliced);
//2
ptrStart += 512;
pathSliced = path.slice(ptrStart, ptrStart+512);
arrayOfRequest.push(pathSliced);
timerElevation = setInterval(request512Elevation, 1000); //1sec
}
//---------------------------------------------------------
function request512Elevation() {
alert("request512Elevation");
// Still has request to be done
if (currentRequestNumber+1 < numberRequestToDo) {
if (!lastRequestElevationFailed) {
currentRequestNumber++;
}
get512Elevation(arrayOfRequest[currentRequestNumber], currentRequestNumber);
}
// All request completed!
else {
clearInterval(timerElevation);
}
}
//------------------------------------------------------------------------------------------------
function get512Elevation(pathSliced, requestNumber) {
alert("get512PointsElevation" + requestNumber);
var locationElevationRequest = {
'locations': pathSliced
}
elevator.getElevationForLocations(locationElevationRequest, function (results, status) {
alert("ResponseReceived for request:" + requestNumber + ", status" + status + " result length:" + results.length);
if (status != google.maps.ElevationStatus.OK) {
lastRequestElevationFailed = true;
return;
}
lastRequestElevationFailed = false;
var elevations = results;
// Extract the elevation samples from the returned results
for (var i = 0; i < results.length; i++) {
elevationPath.push(elevations[i].location);
}
for (var i = 0; i < results.length; i++) {
dataElevation.addRow(['', elevations[i].elevation]);
}
//last reply received? if yes, we can display the elevation graph
if (currentRequestNumber+1 == numberRequestToDo) {
chart.draw(dataElevation, chartOptions);
}
//TODO: how to make sure response are received in correct order (1,2,3)? setInterval reliable enough?
});
}

Underscore with count for duplicate values in angular json array

Can anyone please tell me how to put count in duplicate values in angular JSON array:
My actual array is given below:
$scope.datas.resultsOrder =['Data1','Data2','Data3','Data3','Data4','Data4'];
in the above array Data3 and Data4 is repeating twice, so i need it to come as Data3_1, Data3_2, Data4_1, Data4_2 order within that array like as shown below:
$scope.datas.resultsOrder =['Data1','Data2','Data3_1',
'Data3_2','Data4_1','Data4_2'];
Also the values within that array are dynamic values and not static
Can anyone please tell me some solution for this?
I like UnderscoreJS for these kind of problems. In underscoreJS you can do something like this:
function uniq(array) {
var grouped = _.groupBy(array);
return _.reduce(grouped, function(result, x) {
if(x.length > 1) {
_.each(x, function(val, key) {
result.push(val + '_' + (key + 1));
});
} else {
result.push(x[0]);
}
return result;
},[]);
}
uniq(['Data1','Data2','Data3','Data3','Data4','Data4']);
// ["Data1", "Data2", "Data3_1", "Data3_2", "Data4_1", "Data4_2"]
You can do this:
function transform(arr) {
var c = {};
for (var i = 0; i < arr.length; i++) {
var ar = arr[i];
if(! (ar in c) ) {
c[ar] = 0;
}
c[ar]++;
}
var res = []
;
for(var d in c) {
if(c.hasOwnProperty(d)) {
var l = c[d]
;
if(l === 1) {
res.push(d);
continue;
}
for(var i = 0; i < l; i++) {
res.push(d + '_' + (i + 1));
}
}
}
return res;
}
$scope.datas.resultsOrder = transform(passTheArrayHere);
Note: No guarantee for order.

json not matching model

In EXTJS i will use a model and store for my grid. Now is the problem that sometimes the json will not match the model. There will be less information then in my model. When this happens EXTJS will not show any data in the grid. So i looked for a fix and found this:
Ext.define('App.Reader', {
extend: 'Ext.data.reader.Json',
extractData: function(root) {
var me = this,
values = [],
records = [],
Model = me.model,
i = 0,
length = root.length,
idProp = me.getIdProperty(),
node, id, record;
if (!root.length && Ext.isObject(root)) {
root = [root];
length = 1;
}
for (; i < length; i++) {
node = root[i];
values = me.extractValues(node);
id = me.getId(node);
record = new Model(values, id, node);
records.push(record);
if (me.implicitIncludes) {
me.readAssociated(record, node);
}
}
return records;
},
extractValues: function(data) {
var fields = this.getFields(),
i = 0,
length = fields.length,
output = {},
field, value;
for (; i < length; i++) {
field = fields[i];
value = this.extractorFunctions[i](data);
if(value === undefined)
{
Ext.iterate(fields, function(key, val) {
if (data[key] === undefined & i==val) {
console.log( "Model field <" + key.name + "> does not exist in data/node.");
value = "INVALID OR MISSING FIELD NAME";
var p = 0;
for(var prop in data) {
if(p==i){
if(data.hasOwnProperty(prop))console.log("Instead of <" + key.name + "> we have <" + prop + "> with value <" + data[prop]+ ">");
}
p++;
}
}
}, this);
}
output[field.name] = value;
}
return output;
}
});
var myReader = new App.Reader({
type:'json'
});
i found this online. But when i use this with EXTJS 4.1.1 there is an error in ext-all: TypeError: j is undefined.
Where should i look for the fix for this?
There's no need to do something complicated to solve this trivial problem. Read up on Ext.data.Model and Ext.data.Field, configure your Model properly and you're all set.