Multiple geofencing in ionic - ionic-framework

In my ionic project, I used geofence.
when I open the app in the region the notification is showing.
How can I view the notification only when crossing the border of the geofence.
and I used 3 fences(12Km.300m,50m).when in the range of 50m the app shows the three notification(notifications of three fences).
How i can show the only one notification when i am in the range of the 50m range condition.
in app.component.ts
constructor(public platform: Platform,
public statusBar: StatusBar,
...........) {
this.addGeofence();
}
private addGeofence() {
let fence = [{
id: '69ca1b88-6fbe-4e80-add-sd-4d3748-far',
latitude: 8.556498,
longitude: 76.881820,
radius: 12000,
transitionType: 1,
notification: {
id: 111111111,
title: 'Welcome ',
text: '12km range.',
openAppOnClick: true
}
},
{
id: '69ca1b88-6fbe-4e80-add-sd-4d3748-closevicinity',
latitude: 8.556498,
longitude: 76.881820,
radius: 300,
transitionType: 1,
notification: {
id: 222222222,
title: 'Welcome',
text: '300m range',
openAppOnClick: true
}
},
{
id: '69ca1b88-6fbe-4e80-add-sd-4d3748-near',
latitude: 8.556498,
longitude: 76.881820,
radius: 50,
transitionType: 1,
notification: {
id: 333333333,
title: 'Welcome',
text: '50m range',
openAppOnClick: true
}
},]

My suggestion: You can use the geolocation plugin of ionic to get the current location. Either use this to maybe check location once a minute, or use the background geolocation plugin to do so in background mode. For every location update you get, check whether you are in one of the radii of your geofences. You can use a library like turf to do the mathematics.
If you just want to be notified once you cross the border, save the geofence you were last in into the storage and each time you start the app check, whether the geofence changed.
Be careful though with location subscriptions and background modes as it might cost lots of battery.

Related

How do I get a single set of country boundaries from Mapbox country boundaries

https://codepen.io/m12n/pen/XWNRZMg?editors=0010
mapboxgl.accessToken =
"pk.eyJ1IjoiaW50ZWxsaWdlbmNlZnVzaW9uIiwiYSI6ImNrM2l2cnk1NzBibGIzbm5yaHNycXltZmYifQ.tPEnnW5NAPmInCJDYVfJxA";
var map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/dark-v10",
zoom: 8,
center: [-71.4935, 41.5852]
});
map.on("load", function () {
map.addSource("countries-no-simplification", {
type: "vector",
url: "mapbox://mapbox.country-boundaries-v1"
});
map.addLayer({
id: "countries-simplification-data",
type: "fill",
source: "countries-no-simplification",
"source-layer": "country_boundaries",
paint: {
"fill-color": "#ff69b4",
"fill-opacity": 0.3
}
});
});
The above code and pen shows usage of the MapBox county boundaries where I fill the layer with a colour and a low opacity.
Because the source has multiple world views I get both boundaries for disputed countries showing at the same time, and therefore get the effect shown (stronger colouring).
Eventually I actually want to apply a colour based on a specific datapoint, but for now I would be happy with being able to render only a single set of boundaries (a single world view?).
I cant seem to figure out how to get only one such set of boundaries from the source.
You can apply a filter to keep the boundaries of a specific world view (US, CN, IN, etc.) and remove disputed boundaries. Example:
map.addLayer({
id: "countries-simplification-data",
type: "fill",
source: "countries-no-simplification",
"source-layer": "country_boundaries",
filter: [
'all',
['match', ['get', 'worldview'], ['all', 'US'], true, false],
["!=", "true", ["get", "disputed"]],
],
paint: {
"fill-color": "#ff69b4",
"fill-opacity": 0.3
}
});

Ionic 4 local notification sound not working in Oreo+

I am building an Ionic 4 app and the Local Notification sound was working in Nougat, but is not working Oero.
Is just playing the default sound, and ignoring the sound
I have read here:
https://distriqt.github.io/ANE-PushNotifications/m.FCM-GCM%20Payload
Sounds on individual notifications were deprecated in Android O (API 26). You now have to set them on a channel.
Different notification sound not working in Oreo
that Channel is necessary
this.localNot.schedule({
id: id,
// channel: id, // IS NOT Possible to set
title: title,
text: 'Some text',
sound: `file://assets/audio/mySOUNDFILE.mp3`,
icon: 'file://assets/img/logo/favicon.png', // TODO resident Img,
color: colour
});
But Like I had not field "channel" available in ionic I set an issue here, but was close.
https://github.com/ionic-team/ionic/issues/19696
Do you have a suggestion how can I make it work?
I am using this
"git+https://github.com/Steffaan/cordova-plugin-local-notifications.git",
home.ts
declare var cordova: Cordova;
#Component({
selector: 'app-home', ...
and to send notification
cordova.plugins.notification.local.schedule({
id: Myid,
title: tit,
text: txt,
priority: MyPriority,
channel: 'MyChannel',
sound: `file://assets/audio/${sound}.mp3`,
foreground: true,
lockscreen: true,
vibrate: vib,
wakeup: true,
});
Where
priority: MyPriority,
channel: 'MyChannel',
must be different, for each different sound
in file /node_modules/#types/cordova/index.d.ts I set:
interface CordovaPlugins {
notification: any;
...
}

Catching click event in line graph(ngx-echarts)

I am using echarts Angular version- ngx-echarts in my project. I want to catch click event done on a line graph. chartClick or any of the mouse event of ngx-echarts library is not working for line graphs but they are working for barGraphs. How can I catch click events in line graph using ngx-echarts
<div echarts [options]="chartOption"
(chartClick)="onChartEvent($event, 'chartClick')">
</div>
onChartEvent(event: any, type: string) {
console.log('chart event:', type, event);
}
Logical entity is not entering the onChartEvent function even when click is performed
You can do it by this way.
when you build your options, in series object populate:
series: [
{ // your bar
type: 'bar',
barWidth: '30%',
data: myData
},
{ // shadow bar
type: 'bar',
barWidth: '30%',
itemStyle: {
// transparent bar
normal: { color: 'rgba(0, 0, 0, 0)' }
},
barGap: '-100%',
data: myDataShadow,
animation: false
}
]
Where myDataShow is a copy of myData.
I recommend you put the biggest value in all positions of myDataShadow to make all bar clickable.
In the line chart the 'chartClick' event gets fired only if you click on the points of the lines.
Please go ahead and add the symbol, with that you can click over the point and the event would be triggered. Replace for example triangle over none as shown below:
private mySeries = {
type: 'line',
name: 'prod',
data: myData,
symbol: 'triangle',
itemStyle: {
color: '#35b53a'
}
};

Realtime Tracking using leaflet

I was wondering I can Realtime Tracking my location with leaflet using Ionic ,I was able to get my current location, but I also want to keep track of it when I move
this.map.locate({
setView: true,
maxZoom: 16
}).on('locationfound', (e) => {
let markerGroup = leaflet.featureGroup();
this.marker = leaflet.marker([e.latitude, e.longitude], { icon: carIcon }).addTo(this.map);
locate accepts a watch option that will let you continuously update your marker position:
watch Type: Boolean Default: false
If true, starts continuous watching of location changes (instead of detecting it once) using W3C watchPosition method. You can later stop watching using map.stopLocate() method.
For example:
this.map.locate({
watch: true,
setView: true,
maxZoom: 16
}).on('locationfound', (e) => {
if (!this.marker) {
this.marker = leaflet.marker([e.latitude, e.longitude], { icon: carIcon }).addTo(this.map);
} else {
this.marker.setLatLng([e.latitude, e.longitude]);
}
}

ChartJS / MomentJS - Unable to remove deprecation warning. Graph not showing in firefox/opera

so browsers throw
warning about using momentJS incorrectly.
Deprecation warning: value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
Arguments:
[0] _isAMomentObject: true, _isUTC: false, _useUTC: false, _l: undefined, _i: 12.30, _f: false, _strict: undefined, _locale: [object Object]
Error
So i looked at my code
data: {
labels: ['01.01', '02.01', '03.01', '04.01', '05.01', '06.01', '07.01', '08.01', '09.01', '10.01', '11.01', '12.01'],
datasets: createChatterData(data, this)
},
And read that I should provide a format when dealing with non iso strings.
labels: [moment('01.01', 'MM.DD'), moment('02.01', 'MM.DD'), ...];
Ok that removed first deprecation.
But my datasets data also contains of date
dataset.data.pushObject({
x: moment(datum).format('MM.DD'),
y: parseInt(moment(datum).format('YYYY'))
});
So I tried different variations to that (premodified ambigious datetime)
x: moment(date, 'YYYY.MM.DD').format('MM.DD')
and
x: moment(date, 'MM.DD')
But my graph doesnt map correctly anymore.
Example of codepen chart working in chrome: http://codepen.io/kristjanrein/pen/wJrQLE
Does not display in firefox/opera
I see a couple of issues here.
1) Since you want your X axis to be a time scale, then you should leave your X data value as a moment object. Your current implementation is creating a moment object from a date string and then formatting it back to a string. When you do this, chart.js then takes the string and tries to create a moment object internally when it builds the chart.
Therefore, It is best to keep the data as either a Date or Moment object and use the time scale configuration properties to determine how the data is displayed on the chart. This prevents chart.js from having to construct the moment object and guess at the string format.
2) You are using the pre-2.0 way to create a chart when you use Chart.Scatter. Instead you should use the new style (new Chart()) and pass in a type property.
Here is a modified version of you code that results in no browser warnings and works in Chrome and Firefox (I did not test in Opera).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: myMoment,
y: parseInt(myMoment.format('YYYY')),
};
});
};
var ctx = document.getElementById("chart1").getContext("2d");
var myScatter = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
fill: false,
pointRadius: 4,
pointHoverRadius: 8,
showLine: false,
data: getData()
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Random Data'
},
legend: {
display: true,
labels: {
fontSize: 10,
boxWidth: 20
}
},
elements: {
point: {
pointStyle: 'rect'
}
},
hover: {
mode: 'nearest'
},
scales: {
xAxes: [{
type: 'time',
position: 'bottom',
scaleLabel: {
display: true,
labelString: 'Months'
},
time: {
unit: 'month',
displayFormats: {
month: 'MM'
},
}
}],
yAxes: [ {
type: 'linear',
ticks: {
min: 2005,
max: 2015,
stepSize: 1
},
scaleLabel: {
display: true,
labelString: 'Year'
}
}]
}
}
});
You can see it in action at this forked codepen.
One other thing to keep in mind is that because your data spans multiple years, you will see duplicate months on the X axis. Remember, a time scale is used to plot dates so even if you only display the months, a data point with the same month but with different years will not be plotted at the same location.
If you are actually only wanting to show month string/number values in the X axis, then you should not use the time scale at all and use the linear scale instead. Then when you build your data values, you would extract the month from the data (the same way you are already doing for your Y value).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: parseInt(myMoment.format('MM')),
y: parseInt(myMoment.format('YYYY')),
};
});
};
So in addition to jordan's answer
I changed my labels and x axis from
['01.01', '02.01', ...] to [1,2,...]
and
from type: 'time' to type: 'linear'
And to make it map not only by month but also by day. I had to make date objects to correct floats. 05.20 to 5.66
const date = datum.key;
const day = parseInt(moment(date).format('DD')) / 30 * 100;
const fullDate = parseFloat(moment(date).format('MM') + '.' + Math.round(day))
// 05.10 would be 5.3 (10 of 30 is 33%)
{
x: fullDate,
y: parseInt(moment(date).format('YYYY'))
date: date, // for tooltip
count: count // for tooltip
}
And i also had to make corrections to my tooltips
callbacks: {
title: function([tooltipItem], data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return tooltipInfo.date;
},
label: function(tooltipItem, data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return i18n.t('chart.count') + ': ' + tooltipInfo.count;
},
}
corresponding tooltip dataset
function getTooltip(tooltipItem, datasets) {
return datasets[tooltipItem.datasetIndex].data.find(datum => {
return datum.x === tooltipItem.xLabel && datum.y === tooltipItem.yLabel;
});
}