runningTree中的composeOperation考虑了modi的分支处理

This commit is contained in:
Xu Chang 2024-11-29 11:57:00 +08:00
parent 456324255e
commit cf9d99c9b6
13 changed files with 109 additions and 44 deletions

View File

@ -13,10 +13,10 @@ export default function Locate(props) {
const searchRef = useRef();
// 这里不能用useFeatures因为无法引用lib里面的provider引用src注入是不行的
const featureGeo = useFeatures().geo;
useEffect(() => {
const searchFn = () => {
if (searchValue?.length > 1) {
setSearchLoading(true);
featureGeo.searchPoi(searchValue).then((result) => {
featureGeo.searchPoi(searchValue, props.areaId, undefined, 0, 10).then((result) => {
setSearchLoading(false);
setPois(result.map((ele, idx) => ({
...ele,
@ -33,9 +33,14 @@ export default function Locate(props) {
else {
setPois(undefined);
}
};
let handle;
useEffect(() => {
handle = setTimeout(searchFn, 1000);
}, [searchValue]);
const center = currentPoi?.coordinate || props.coordinate;
const Locate = (<List className={Styles["location-list"]} header={<Input ref={searchRef} placeholder="请输入完整名称(如“浙江大学”)而非简称(如“浙大”)" value={searchValue} allowClear onChange={(e) => {
clearTimeout(handle);
setSearchValue(e.target.value);
}} prefix={<SearchOutlined />} onFocus={() => {
setMode('searchPoi');
@ -76,6 +81,7 @@ export default function Locate(props) {
return (<Row gutter={[16, 16]} style={{
width: '100%',
minHeight: 600,
maxHeight: '100%',
}}>
<Col xs={24} sm={14}>
<Map2 style={{ height: '100%' }} id="location-map" center={center} markers={center ? [center] : undefined}/>

View File

@ -1,6 +1,8 @@
.location-list {
width: 100%;
height: 100%;
overflow-y: scroll;
max-height: 600px;
display: flex;
flex-direction: column;

View File

@ -1,4 +1,5 @@
import { assert } from 'oak-domain/lib/utils/assert';
import { wgs84togcj02 } from 'oak-domain/lib/utils/geo';
import React, { useEffect, useState } from 'react';
import OlMap from 'ol/Map';
import Feature from 'ol/Feature';
@ -27,6 +28,7 @@ export default function Map(props) {
layers: [
new TileLayer({
source: new XYZ({
// 用的高德的瓦片gcj02坐标
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
wrapX: false,
}),
@ -36,7 +38,7 @@ export default function Map(props) {
}),
],
view: new View({
center: fromLonLat(props.center || DEFAULT_CENTER),
center: fromLonLat(wgs84togcj02(props.center || DEFAULT_CENTER)),
zoom: props.zoom || DEFAULT_ZOOM,
minZoom: props.unzoomable ? props.zoom : undefined,
maxZoom: props.unzoomable ? props.zoom : undefined,
@ -59,7 +61,7 @@ export default function Map(props) {
}
if (!props.center) {
locate().then(({ latitude, longitude }) => {
map2.getView().setCenter(fromLonLat([longitude, latitude]));
map2.getView().setCenter(fromLonLat(wgs84togcj02([longitude, latitude])));
});
}
setMap(map2);
@ -71,13 +73,13 @@ export default function Map(props) {
const oc2 = toLonLat(originCenter);
if (oc2[0] !== props.center[0] || oc2[1] !== props.center[1]) {
map.getView().animate({
center: fromLonLat(props.center),
center: fromLonLat(wgs84togcj02(props.center)),
duration: 500,
});
}
}
else {
map.getView().setCenter(fromLonLat(props.center));
map.getView().setCenter(fromLonLat(wgs84togcj02(props.center)));
}
}
}, [props.center]);
@ -92,11 +94,11 @@ export default function Map(props) {
let feature = markerLayer.getSource().getFeatureById('markers');
if (feature) {
// feature.setGeometry(new MultiPoint(props.markers.map(ele => fromLonLat(ele))));
feature.setGeometry(new Point(fromLonLat(props.markers[0])));
feature.setGeometry(new Point(fromLonLat(wgs84togcj02(props.markers[0]))));
}
else {
// feature = new Feature(new MultiPoint(props.markers.map(ele => fromLonLat(ele))));
feature = new Feature(new Point(fromLonLat(props.markers[0])));
feature = new Feature(new Point(fromLonLat(wgs84togcj02(props.markers[0]))));
feature.setStyle(new Style({
image: new Circle({
// 点的颜色

View File

@ -5,7 +5,7 @@ import { Cache } from './cache';
export declare class Geo<ED extends EntityDict & BaseEntityDict> extends Feature {
private cache;
constructor(cache: Cache<ED>);
searchPoi(name: string, areaId?: string, typeCode?: string): Promise<{
searchPoi(name: string, areaId?: string, typeCode?: string, indexFrom?: number, count?: number): Promise<{
poiName: string;
areaId: string;
latitude: number;

View File

@ -5,12 +5,14 @@ export class Geo extends Feature {
super();
this.cache = cache;
}
async searchPoi(name, areaId, typeCode) {
async searchPoi(name, areaId, typeCode, indexFrom, count) {
const { result } = await this.cache.exec('geoService', {
api: 'geo',
params: {
name,
areaId
areaId,
indexFrom,
count,
}
});
return result;

View File

@ -156,7 +156,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
*/
updateItem(lsn: number, data: ED[T]['Update']['data'], id: string, action?: ED[T]['Action']): void;
updateItems(lsn: number, data: Record<string, ED[T]['Update']['data']>, ids: string[], action?: ED[T]['Action']): void;
composeOperations(): Array<{
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined;
@ -214,7 +214,12 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
update(lsn: number, data: ED[T]['Update']['data'], action?: ED[T]['Action']): void;
remove(lsn: number): void;
setDirty(): void;
composeOperations(fromParent?: boolean): Array<{
/**
*
* @param includeModiBranch boolean
* @returns
*/
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined;
@ -249,7 +254,7 @@ declare class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Node<E
destroy(): void;
getFreshValue(): undefined;
refresh(): Promise<void>;
composeOperations(): Array<{
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined;

View File

@ -827,14 +827,14 @@ class ListNode extends EntityNode {
ids.forEach((id) => this.updateItemInner(lsn, data, id, action));
this.setDirty();
}
composeOperations() {
composeOperations(includeModiBranch) {
if (!this.dirty) {
return;
}
const intrinsticFilter = this.getIntrinsticFilters();
const ulmLsn = this.ulManager.maxLsn;
for (const id in this.children) {
const childOperations = this.children[id].composeOperations(true);
const childOperations = this.children[id].composeOperations(includeModiBranch);
if (childOperations) {
childOperations.forEach((childOperation) => this.ulManager.push(ulmLsn + 100, childOperation.operation));
}
@ -1315,13 +1315,22 @@ class SingleNode extends EntityNode {
});
super.setDirty();
}
composeOperations(fromParent) {
/**
*
* @param includeModiBranch 如果显式置了boolean代表只要考虑前项路径或者后项路径
* @returns
*/
composeOperations(includeModiBranch) {
if (this.dirty) {
const lsnMax = this.ulManager.maxLsn;
for (const ele in this.children) {
if (ele.includes(MODI_NEXT_PATH_SUFFIX) && false === includeModiBranch ||
(!ele.includes(MODI_NEXT_PATH_SUFFIX) && true === includeModiBranch)) {
continue;
}
const ele2 = ele.includes(':') ? ele.slice(0, ele.indexOf(':')) : ele;
const child = this.children[ele];
const childOperations = child.composeOperations(true);
const childOperations = child.composeOperations(includeModiBranch);
if (childOperations) {
if (child instanceof SingleNode) {
assert(childOperations.length === 1);
@ -1680,14 +1689,18 @@ class VirtualNode extends Node {
throw err;
}
}
composeOperations() {
composeOperations(includeModiBranch) {
/**
* 当一个virtualNode有多个子结点而这些子结点的前缀一致时标识这些子结点其实是指向同一个对象此时需要合并
*/
const operationss = [];
const operationDict = {};
for (const ele in this.children) {
const operation = this.children[ele].composeOperations(true);
if (ele.includes(MODI_NEXT_PATH_SUFFIX) && false === includeModiBranch ||
(!ele.includes(MODI_NEXT_PATH_SUFFIX) && true === includeModiBranch)) {
continue;
}
const operation = this.children[ele].composeOperations(includeModiBranch);
if (operation) {
const idx = ele.indexOf(':') !== -1 ? ele.slice(0, ele.indexOf(':')) : ele;
if (operationDict[idx]) {
@ -1928,7 +1941,7 @@ export class RunningTree extends Feature {
redoBranchOperations(path, allowInTxn) {
const { root } = analyzePath(path);
const rootNode = this.root[root];
const opers = rootNode.composeOperations();
const opers = rootNode.composeOperations(path.includes(MODI_NEXT_PATH_SUFFIX));
if (opers) {
this.cache.redoOperation(opers);
}

View File

@ -5,7 +5,7 @@ import { Cache } from './cache';
export declare class Geo<ED extends EntityDict & BaseEntityDict> extends Feature {
private cache;
constructor(cache: Cache<ED>);
searchPoi(name: string, areaId?: string, typeCode?: string): Promise<{
searchPoi(name: string, areaId?: string, typeCode?: string, indexFrom?: number, count?: number): Promise<{
poiName: string;
areaId: string;
latitude: number;

View File

@ -8,12 +8,14 @@ class Geo extends Feature_1.Feature {
super();
this.cache = cache;
}
async searchPoi(name, areaId, typeCode) {
async searchPoi(name, areaId, typeCode, indexFrom, count) {
const { result } = await this.cache.exec('geoService', {
api: 'geo',
params: {
name,
areaId
areaId,
indexFrom,
count,
}
});
return result;

View File

@ -156,7 +156,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
*/
updateItem(lsn: number, data: ED[T]['Update']['data'], id: string, action?: ED[T]['Action']): void;
updateItems(lsn: number, data: Record<string, ED[T]['Update']['data']>, ids: string[], action?: ED[T]['Action']): void;
composeOperations(): Array<{
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined;
@ -214,7 +214,12 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
update(lsn: number, data: ED[T]['Update']['data'], action?: ED[T]['Action']): void;
remove(lsn: number): void;
setDirty(): void;
composeOperations(fromParent?: boolean): Array<{
/**
*
* @param includeModiBranch boolean
* @returns
*/
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined;
@ -249,7 +254,7 @@ declare class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Node<E
destroy(): void;
getFreshValue(): undefined;
refresh(): Promise<void>;
composeOperations(): Array<{
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined;

View File

@ -830,14 +830,14 @@ class ListNode extends EntityNode {
ids.forEach((id) => this.updateItemInner(lsn, data, id, action));
this.setDirty();
}
composeOperations() {
composeOperations(includeModiBranch) {
if (!this.dirty) {
return;
}
const intrinsticFilter = this.getIntrinsticFilters();
const ulmLsn = this.ulManager.maxLsn;
for (const id in this.children) {
const childOperations = this.children[id].composeOperations(true);
const childOperations = this.children[id].composeOperations(includeModiBranch);
if (childOperations) {
childOperations.forEach((childOperation) => this.ulManager.push(ulmLsn + 100, childOperation.operation));
}
@ -1318,13 +1318,22 @@ class SingleNode extends EntityNode {
});
super.setDirty();
}
composeOperations(fromParent) {
/**
*
* @param includeModiBranch 如果显式置了boolean代表只要考虑前项路径或者后项路径
* @returns
*/
composeOperations(includeModiBranch) {
if (this.dirty) {
const lsnMax = this.ulManager.maxLsn;
for (const ele in this.children) {
if (ele.includes(exports.MODI_NEXT_PATH_SUFFIX) && false === includeModiBranch ||
(!ele.includes(exports.MODI_NEXT_PATH_SUFFIX) && true === includeModiBranch)) {
continue;
}
const ele2 = ele.includes(':') ? ele.slice(0, ele.indexOf(':')) : ele;
const child = this.children[ele];
const childOperations = child.composeOperations(true);
const childOperations = child.composeOperations(includeModiBranch);
if (childOperations) {
if (child instanceof SingleNode) {
(0, assert_1.assert)(childOperations.length === 1);
@ -1683,14 +1692,18 @@ class VirtualNode extends Node {
throw err;
}
}
composeOperations() {
composeOperations(includeModiBranch) {
/**
* 当一个virtualNode有多个子结点而这些子结点的前缀一致时标识这些子结点其实是指向同一个对象此时需要合并
*/
const operationss = [];
const operationDict = {};
for (const ele in this.children) {
const operation = this.children[ele].composeOperations(true);
if (ele.includes(exports.MODI_NEXT_PATH_SUFFIX) && false === includeModiBranch ||
(!ele.includes(exports.MODI_NEXT_PATH_SUFFIX) && true === includeModiBranch)) {
continue;
}
const operation = this.children[ele].composeOperations(includeModiBranch);
if (operation) {
const idx = ele.indexOf(':') !== -1 ? ele.slice(0, ele.indexOf(':')) : ele;
if (operationDict[idx]) {
@ -1931,7 +1944,7 @@ class RunningTree extends Feature_1.Feature {
redoBranchOperations(path, allowInTxn) {
const { root } = analyzePath(path);
const rootNode = this.root[root];
const opers = rootNode.composeOperations();
const opers = rootNode.composeOperations(path.includes(exports.MODI_NEXT_PATH_SUFFIX));
if (opers) {
this.cache.redoOperation(opers);
}

View File

@ -15,12 +15,14 @@ export class Geo<
this.cache = cache;
}
async searchPoi(name: string, areaId?: string, typeCode?: string) {
async searchPoi(name: string, areaId?: string, typeCode?: string, indexFrom?: number, count?: number) {
const { result } = await this.cache.exec('geoService', {
api: 'geo',
params: {
name,
areaId
areaId,
indexFrom,
count,
}
});

View File

@ -409,7 +409,7 @@ class ListNode<
private filters: (NamedFilterItem<ED, T> & { applied?: boolean })[];
private sorters: (NamedSorterItem<ED, T> & { applied?: boolean })[];
private getTotal?: number;
private pagination: Pagination = { ...DEFAULT_PAGINATION};
private pagination: Pagination = { ...DEFAULT_PAGINATION };
private sr: Record<string, any> = {};
private syncHandler: (records: OpRecord<ED>[]) => void;
@ -1036,7 +1036,7 @@ class ListNode<
this.setDirty();
}
composeOperations():
composeOperations(includeModiBranch?: boolean):
| Array<{ entity: keyof ED; operation: ED[keyof ED]['Operation'] }>
| undefined {
if (!this.dirty) {
@ -1047,7 +1047,7 @@ class ListNode<
const ulmLsn = this.ulManager.maxLsn;
for (const id in this.children) {
const childOperations = this.children[id].composeOperations(true);
const childOperations = this.children[id].composeOperations(includeModiBranch);
if (childOperations) {
childOperations.forEach(
(childOperation) => this.ulManager.push(ulmLsn + 100, childOperation.operation as any)
@ -1614,16 +1614,25 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
super.setDirty();
}
composeOperations(fromParent?: boolean): Array<{
/**
*
* @param includeModiBranch boolean
* @returns
*/
composeOperations(includeModiBranch?: boolean): Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}> | undefined {
if (this.dirty) {
const lsnMax = this.ulManager.maxLsn;
for (const ele in this.children) {
if (ele.includes(MODI_NEXT_PATH_SUFFIX) && false === includeModiBranch ||
(!ele.includes(MODI_NEXT_PATH_SUFFIX) && true === includeModiBranch)) {
continue;
}
const ele2 = ele.includes(':') ? ele.slice(0, ele.indexOf(':')) : ele;
const child = this.children[ele];
const childOperations = child!.composeOperations(true);
const childOperations = child!.composeOperations(includeModiBranch);
if (childOperations) {
if (child instanceof SingleNode) {
assert(childOperations.length === 1);
@ -2015,14 +2024,18 @@ class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Node<ED> {
throw err;
}
}
composeOperations(): Array<{ entity: keyof ED, operation: ED[keyof ED]['Operation'] }> | undefined {
composeOperations(includeModiBranch?: boolean): Array<{ entity: keyof ED, operation: ED[keyof ED]['Operation'] }> | undefined {
/**
* virtualNode有多个子结点
*/
const operationss = [];
const operationDict: Record<string, any> = {};
for (const ele in this.children) {
const operation = this.children[ele].composeOperations(true);
if (ele.includes(MODI_NEXT_PATH_SUFFIX) && false === includeModiBranch ||
(!ele.includes(MODI_NEXT_PATH_SUFFIX) && true === includeModiBranch)) {
continue;
}
const operation = this.children[ele].composeOperations(includeModiBranch);
if (operation) {
const idx = ele.indexOf(':') !== -1 ? ele.slice(0, ele.indexOf(':')) : ele;
if (operationDict[idx]) {
@ -2338,7 +2351,7 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
const { root } = analyzePath(path);
const rootNode = this.root[root];
const opers = rootNode.composeOperations();
const opers = rootNode.composeOperations(path.includes(MODI_NEXT_PATH_SUFFIX));
if (opers) {
this.cache.redoOperation(opers);
}