Обзавелся давече мечтой — мотоциклом. Соответственно нужно открыть категорию А. Мотошколы просят прежде пройти водительскую комиссию. А это как было 10 лет назад квестом, так и осталось. Вот текущий порядок действий:
Взять бланк для прохождения комиссии в любом учреждении оказывающей эту услугу
Пройти врача-психиатра. Предварительная запись 29-06-29. Очередь примерно 8 дней. Стоимость 900р. При записи дадут код который нужно будет ввести в и получить талончик в терминале. Залинейная-29. Ставит запись в бланке
Пройти врача-психиатра-нарколога. Набережная 6 армии, 139. Без записи. Стоимость 500р. Ставит запись в бланке.
С бланками вернутся в п.1, где брали бланк и пройти оставшихся специалистов.
Нет, всё таки версия 3 еще сыровата для внедрения в прод. Ну или «лыжи не едут». Для решения простой задачи — отображение подсказки над полигоном, пришлось переписываться с тех поддержкой яндекса (и они даже ответили!, чем я безмерно удивлён). В результате родился скрипт, в котором требуется переопределение вызовов класса. Хм.. это определенно не то что хочется видеть для получения базовых вещей, которые в версии 2.1 работают «из коробки».
async function main() {
await ymaps3.ready;
ymaps3.import.registerCdn('https://cdn.jsdelivr.net/npm/{package}',['@yandex/ymaps3-hint@0.0.1']);
const {YMap,YMapDefaultSchemeLayer,YMapFeature,YMapDefaultFeaturesLayer,YMapFeatureSource,YMapFeatureDataSource,YMapEntity} = ymaps3;
const {YMapHint,YMapHintContext} = await ymaps3.import('@yandex/ymaps3-hint');
map = new ymaps3.YMap(
document.getElementById('app'),
{location:
{
center: [39.8491648, 59.2084992],
zoom: 9
},
showScaleInCopyrights: false //шкала масштаба рядом в логотипом
}
);
const defaultScheme = new YMapDefaultSchemeLayer({}); // Добавляем рисованное изображение карты
map.addChild(defaultScheme);
const features = new YMapDefaultFeaturesLayer();
map.addChild(features);
//получаем список районов
common.AjaxPost("index.php?r=site2/get-areas","").then(async areas_list=>{
console.log("-прочитал список районов ",areas_list);
if (areas_list.error==false){
for (var i = 0; i < areas_list.result.length; i++) {
await common.AjaxPost("areas/"+areas_list.result[i].poly_filename,"aa").then(res2=>{
console.log(areas_list.result[i].name);
res2=common.ReverseCoors(res2);
console.log(areas_list.result[i].poly_fill_color);
const polygon = new ymaps3.YMapFeature({
geometry: {
type: 'Polygon',
coordinates: res2
},
properties: {
hint: areas_list.result[i].name+" район"
},
style: {
stroke: [
{
color: '#196DFF99',
dash: [5, 10],
width: 3
}
],
fillOpacity: 0.2,
fill: "#"+areas_list.result[i].poly_fill_color
}
});
features.addChild(polygon);
});
};
};
});
const hint = new YMapHint({
layers: [features.layer],
hint: object => object?.properties?.hint
});
map.addChild(hint);
hint.addChild(
new(
class MyHint extends YMapEntity {
_onAttach() {
this._element =document.createElement('div');
this._element.className ='hint';
this._detachDom =ymaps3.useDomContext(this,this._element);
this._watchContext(
YMapHintContext,
() => {
const context =this._consumeContext(YMapHintContext);
this._element.textContent =(context?.hint || '');
console.log(this._element);
}, {
immediate: true
}
);
}
_onDetach() {this._detachDom();}
}
)()
);
};
window.map = null;
main();
Пока на работе выдалась небольшая творческая пауза, решил потыкать API версии 3, который приходит на смену версии 2.1 И рано или поздно как я понимаю версия 2.1 будет отключена. А проекты на «старой» версии есть.
Так вот, что не понравилось: все примеры в «песочнице», на typescript, а не на чистом javascript. Ну и полностью всё конечно поломано, т.е. не получится просто взять старый код, и чуть адаптировать — нужно всё переписывать. Вплоть до того что, они даже координаты «перевернули» местами, пришлось для того чтобы наложить полигоны районов со старой карты на новую, их «переворачивать».
Ну собственно, вот код,
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script src="https://api-maps.yandex.ru/v3/?apikey=уууу&lang=ru_RU" type="text/javascript"></script>
<div id="app"></div>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel" src="ts/variables.ts"></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel" src="ts/common.ts"></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel" src="ts/receipts.ts"></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
import * as common from '../common';
async function main() {
await ymaps3.ready;
const {YMap, YMapDefaultSchemeLayer,YMapFeature,YMapDefaultFeaturesLayer} = ymaps3;
map = new YMap(
document.getElementById('app'),
{location:
{
center: [39.8491648, 59.2084992],
zoom: 9
},
showScaleInCopyrights: true
},
[
new YMapDefaultSchemeLayer({}),
new YMapDefaultFeaturesLayer({})
],
);
//получаем список районов
common.AjaxPost("index.php?r=site2/get-areas","").then(async areas_list=>{
console.log("-прочитал список районов ",areas_list);
if (areas_list.error==false){
for (var i = 0; i < areas_list.result.length; i++) {
await common.AjaxPost("areas/"+areas_list.result[i].poly_filename,"aa").then(res2=>{
console.log(areas_list.result[i].name);
res2=common.ReverseCoors(res2);
console.log(areas_list.result[i].poly_fill_color);
const polygon = new YMapFeature({
geometry: {
type: 'Polygon',
coordinates: res2
},
properties:{
hintContent: areas_list.result[i].name
},
// Описание тут: https://yandex.ru/maps-api/docs/js-api/ref/index.html#interface-drawingstyle
style: {
stroke: [
{
color: '#196DFF99',
dash: [5, 10],
width: 3
}
],
fillOpacity: 0.2,
fill: "#"+areas_list.result[i].poly_fill_color
}
});
console.log(polygon);
map.addChild(polygon);
});
};
};
});
};
window.map = null;
main();
</script>
common.ts:
/**
Получаем информацию об очертаниях районов (округов)
*/
export async function AjaxPost(url : string,payload: any): any {
try {
const response = await fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json; charset=UTF-8' },
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(HTTP error! Status: ${response.status});
}
return response.json();
} catch (error) {
console.error('Error:', error);
throw error;
}
}
/**
Сделать паузу в милисекундах
*/
export async function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
Перевернуть все координаты в массиве
*/
export function ReverseCoors(coors : any): any {
for (var ii = 0; ii < coors.length; ii++) {
for (var iii = 0; iii < coors[ii].length; iii++) {
var x=0;
var y=0;
x=coors[ii][iii][0];
y=coors[ii][iii][1];
coors[ii][iii][1]=x;
coors[ii][iii][0]=y;
};
};
return coors;
}
Если требуется обработать и показать данные по выбранному диапазону, то необходимо использовать в запросе переменные $__from и $__to. Однако стоит учитывать, что они в запросе встают как время с эпохи unix. А именно большое длинное число. Поэтому если например в БД у даты типа дата, без времени, то приходится использовать преобразование вида:
EXTRACT(EPOCH from agreements_dt)*1000
Чтобы из даты вида 2026-01-01 получить 1767214800000. Ну и соответственно в запросе:
select to_char(date_trunc('day', dt), 'YYYY-MM-DD'),count(*) as "Великоустюгское территориальное отделение" from (
select
date_trunc('month', agreements_dt)::date as dt
from
ls
where EXTRACT(EPOCH from agreements_dt)*1000 between $__from and $__to and owner='000000003' and agreements_dt is not null
) as agr
group by dt
order by dt asc
Иногда при построении графика (например Bar chart) на основании запроса в PostreSQL, дата отображается не верно, а именно, примерно так:
Для того чтобы сиё поправить, нужно привести дату строго в формат YYYY-MM-DD. Например так:
select to_char(date_trunc('day', dt), 'YYYY-MM-DD'),count(*) as "${division:text}" from (
select
date_trunc('month', agreements_dt)::date as dt
from
ls
where agreements_dt>'2018-01-01' and
owner in ('$division') and
agreements_dt is not null
) as agr
group by dt
order by dt desc