단속연계파일 파싱 수정

main
이범준 1 year ago
parent 6ffa467974
commit 844db5100d

@ -8,14 +8,17 @@ import java.nio.charset.Charset;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import org.apache.commons.io.FilenameUtils;
import cokr.xit.foundation.data.DataObject;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import net.minidev.json.parser.JSONParser;
public class AttachedTxtParser extends LayoutParser{
@ -33,7 +36,7 @@ public class AttachedTxtParser extends LayoutParser{
List<DataObject> dataObjectList = new ArrayList<>();
sortedFileList.forEach(item -> {
DataObject dataObject = new DataObject();
DataObject dataObject = this.createParsedDataObject();
dataObject.put("FILE_GROUP_TYPE", "TXT");
File file = item.toFile();
@ -56,58 +59,86 @@ public class AttachedTxtParser extends LayoutParser{
String noExtensionName = FilenameUtils.removeExtension(fileName);
String[] fileNameSplit = noExtensionName.split(Matcher.quoteReplacement(descriptor.getFileNameSeperator()));
this.analyzeFileName(dataObject, noExtensionName);
String crdnTiemstamp = fileNameSplit[0];
dataObject.put("CRDN_YMD", crdnTiemstamp.substring(0, 8));
dataObject.put("CRDN_TM", crdnTiemstamp.substring(8, 14));
this.refineValue(dataObject);
dataObject.put("ENT_CD", fileNameSplit[1]);
dataObject.put("EQPMNT_CD", fileNameSplit[2]);
dataObject.put("FILE_SEQ", fileNameSplit[3]);
boolean isMetaData = fileExtension.toUpperCase().equals("TXT");
try {
JSONParser jsonParser = new JSONParser(-1);
JSONArray jsonArray = (JSONArray)jsonParser.parse(descriptor.getContentItems());
if(isMetaData) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(file),Charset.forName("EUC-KR")));
String line1 = br.readLine();
String[] lineSplit = line1.split(Matcher.quoteReplacement(","));
dataObject.put("VHRNO", lineSplit[0]);
dataObject.put("CRDN_STDG_NM", lineSplit[1]);
dataObject.put("CRDN_PLC", lineSplit[2]);
dataObject.put("LAW", lineSplit[3]);
dataObject.put("SPECIAL_AREA", lineSplit[4]);
dataObject.put("CRDN_BGNG_TM", lineSplit[5]);
dataObject.put("CRDN_END_TM", lineSplit[6]);
String line2 = br.readLine();
if(line2 != null && !line2.equals("")) {
dataObject.put("CRDN_SE_CD", "02");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),Charset.forName("EUC-KR")));
String content = org.apache.commons.io.IOUtils.toString(br);
String[] contentDivision = null;
String part = "";
int contentDivisionIndex = 0;
int partSplitCursor = 0;
dataObject.put("GPS_X", line2);
String line3 = br.readLine();
dataObject.put("GPS_Y", line3);
if(!descriptor.getContentSecondSeperator().equals("")) {
contentDivision = smartSplit(content, descriptor.getContentSecondSeperator());
part = contentDivision[contentDivisionIndex];
} else {
part = content;
}
for(int i=0; i<jsonArray.size(); i++) {
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
String key = jsonObject.keySet().iterator().next();
if(Arrays.asList(descriptor.getSecondSeperatorStarterItems().split(",")).contains(key)) {
contentDivisionIndex++;
partSplitCursor = 0;
if(contentDivision.length > contentDivisionIndex) {
part = contentDivision[contentDivisionIndex];
} else {
part = "";
}
}
String[] partSplit = smartSplit(part, descriptor.getContentSeperator());
if(partSplit.length > partSplitCursor) {
dataObject.put(key, partSplit[partSplitCursor]);
} else {
dataObject.put(key, "");
}
partSplitCursor++;
}
//
if(descriptor.getTaskSeCd().equals("PVS") || descriptor.getTaskSeCd().equals("BPV")) {
if(descriptor.getEnterpriseName().equals("xit")) {
if(!dataObject.string("GPS_X").equals("")) {
dataObject.put("CRDN_SE_CD", "02");
} else {
dataObject.put("CRDN_SE_CD", "01");
}
}
}
this.refineValue(dataObject);
} else {
for(int i=0; i<jsonArray.size(); i++) {
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
String key = jsonObject.keySet().iterator().next();
dataObject.put(key, "");
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
dataObject.put("VHRNO", "");
dataObject.put("CRDN_STDG_NM", "");
dataObject.put("CRDN_PLC", "");
dataObject.put("LAW", "");
dataObject.put("SPECIAL_AREA", "");
dataObject.put("CRDN_BGNG_TM", "");
dataObject.put("CRDN_END_TM", "");
dataObject.put("GPS_X", "");
dataObject.put("GPS_Y", "");
}
if(!before.isEmpty()) {
boolean isChangeTempGroup = this.isChangeCrackdown(dataObject, before);

@ -0,0 +1,53 @@
package cokr.xit.fims.crdn.parsing;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import cokr.xit.base.code.CommonCode;
import cokr.xit.foundation.data.DataObject;
public class CodeConverter {
Map<String, List<CommonCode>> commonCodes = new HashMap<String, List<CommonCode>>();
CodeConverter(Map<String, List<CommonCode>> commonCodes){
this.commonCodes = commonCodes;
}
String valueToCode(String codeGroupName, String value){
String result = "";
List<CommonCode> commonCodeList = commonCodes.get(codeGroupName);
for(int i = 0; i < commonCodeList.size(); i++) {
if(value.replaceAll(Matcher.quoteReplacement(" "), "").equals(commonCodeList.get(i).getValue().replaceAll(Matcher.quoteReplacement(" "), ""))) {
result = commonCodeList.get(i).getCode();
}
}
return result;
}
String codeToValue(String codeGroupName, String code){
String result = "";
List<CommonCode> commonCodeList = commonCodes.get(codeGroupName);
for(int i = 0; i < commonCodeList.size(); i++) {
if(code.equals(commonCodeList.get(i).getCode())) {
result = commonCodeList.get(i).getValue();
}
}
return result;
}
public void fillIfEmpty(DataObject dataObject, String codeGroupName, String codeName, String valueName) {
if(!dataObject.string(valueName).equals("") && dataObject.string(codeName).equals("")) {
dataObject.put(codeName, this.valueToCode(codeGroupName, dataObject.string(valueName)));
} else if(dataObject.string(valueName).equals("") && !dataObject.string(codeName).equals("")) {
dataObject.put(valueName, this.codeToValue(codeGroupName, dataObject.string(codeName)));
}
}
}

@ -82,6 +82,11 @@ public class LayoutDescriptor {
*/
private String secondSeperatorStarterItems;
/**
*
*/
private String enterpriseName;
/**
*
*/

@ -1,12 +1,63 @@
package cokr.xit.fims.crdn.parsing;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import cokr.xit.base.code.CommonCode;
import cokr.xit.foundation.data.DataObject;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import net.minidev.json.parser.JSONParser;
import net.minidev.json.parser.ParseException;
abstract public class LayoutParser {
String[] allItem = {
"FILE_GROUP_TYPE","FILE_PATH","FILE_NAME","FILE_LAST_MODIFIED","FILE_SIZE","FILE_EXTENSION","LINK_ENT_NM","ENT_NM",
"FILE_SEQ","PHOTO_CNT","PHOTO_TYPE_CD","PHOTO_TYPE_NM","FILE_STATUS_CD","FILE_STATUS_NM",
"VHRNO",
"CRDN_TIMESTAMP","CRDN_YMD_TM","CRDN_YMD","CRDN_TM","CRDN_END_TM","CRDN_BGNG_TM",
"CRDN_PLC","CRDN_ROAD_NM","CRDN_STDG_NM","GPS_X","GPS_Y","CRDN_SPAREA_NM","CRDN_SPAREA_CD",
"BZENTY_CD","TEAM_ID","EQPMNT_CD","CRDN_SE_CD","CRDN_SE_NM",
"MOSC_X","MOSC_Y","PLATE_WIDTH","PLATE_HEIGHT",
"VLTN_CD","VLTN_NM","CRDN_CN_CD","CRDN_CN_NM",
"CAR_VELOCITY"
};
public DataObject createParsedDataObject() {
DataObject dataObject = new DataObject();
for(int i=0; i < allItem.length; i++) {
dataObject.put(allItem[i], "");
}
return dataObject;
}
Map<String, List<CommonCode>> allCode = new HashMap<String, List<CommonCode>>(){{
put("PHOTO_TYPE",new ArrayList<>() {{
add(new CommonCode() {{ setCode("1"); setValue("입차사진"); }});
add(new CommonCode() {{ setCode("2"); setValue("주차사진"); }});
add(new CommonCode() {{ setCode("3"); setValue("위반사진"); }});
add(new CommonCode() {{ setCode("4"); setValue("출차사진"); }});
}});
put("FILE_STATUS",new ArrayList<>() {{
add(new CommonCode() {{ setCode("S"); setValue("정상등록자료"); }});
add(new CommonCode() {{ setCode("E"); setValue("삭제자료"); }});
}});
put("CRDN_CN",new ArrayList<>() {{
add(new CommonCode() {{ setCode("00"); setValue("사용안함"); }});
add(new CommonCode() {{ setCode("01"); setValue("일반차량(전기차)"); }});
add(new CommonCode() {{ setCode("02"); setValue("장기주차(전기차)"); }});
}});
}};
public void addCommonCode(Map<String, List<CommonCode>> commonCode) {
this.allCode.putAll(commonCode);
}
LayoutDescriptor descriptor = new LayoutDescriptor();
public void setDescriptor(LayoutDescriptor descriptor) {
@ -25,4 +76,97 @@ abstract public class LayoutParser {
*/
abstract public boolean isChangeCrackdown(DataObject currentItem, DataObject beforeItem);
/** .<br />
* @param dataObject
* @return
*/
public void refineValue(DataObject dataObject) {
//단속일시 설정
if(!dataObject.string("CRDN_TIMESTAMP").equals("")) {
dataObject.put("CRDN_YMD", dataObject.string("CRDN_TIMESTAMP").substring(0, 8));
dataObject.put("CRDN_TM", dataObject.string("CRDN_TIMESTAMP").substring(8, 14));
dataObject.put("CRDN_YMD_TM", dataObject.string("CRDN_TIMESTAMP").substring(0, 14));
} else if(!dataObject.string("CRDN_YMD_TM").equals("")) {
dataObject.put("CRDN_YMD", dataObject.string("CRDN_YMD_TM").substring(0, 8));
dataObject.put("CRDN_TM", dataObject.string("CRDN_YMD_TM").substring(8, 14));
dataObject.put("CRDN_TIMESTAMP", dataObject.string("CRDN_YMD_TM")+"000");
} else if(!dataObject.string("CRDN_YMD").equals("")){
dataObject.put("CRDN_YMD_TM", dataObject.string("CRDN_YMD")+dataObject.string("CRDN_TM"));
dataObject.put("CRDN_TIMESTAMP", dataObject.string("CRDN_YMD")+dataObject.string("CRDN_TM")+"000");
}
CodeConverter codeConverter = new CodeConverter(allCode);
//위반내용
String vltnGroup = "";
switch (descriptor.getTaskSeCd()) {
case "PVS" -> { vltnGroup = "WEB002"; }
case "BPV" -> { vltnGroup = "FIM005"; }
case "DPV" -> { vltnGroup = "FIM006"; }
case "ECA" -> { vltnGroup = "FIM061"; }
}
if(!vltnGroup.equals("")) {
codeConverter.fillIfEmpty(dataObject, vltnGroup, "VLTN_CD", "VLTN_NM");
}
//특별구역
codeConverter.fillIfEmpty(dataObject, "FIM007", "CRDN_SPAREA_CD", "CRDN_SPAREA_NM");
codeConverter.fillIfEmpty(dataObject, "PHOTO_TYPE", "PHOTO_TYPE_CD", "PHOTO_TYPE_NM");
codeConverter.fillIfEmpty(dataObject, "FILE_STATUS", "FILE_STATUS_CD", "FILE_STATUS_NM");
codeConverter.fillIfEmpty(dataObject, "CRDN_CN", "CRDN_CN_CD", "CRDN_CN_NM");
}
/** .<br />
* @param dataObject
* @return
*/
public void analyzeFileName(DataObject dataObject, String noExtensionName) {
String fileNameItmesJSONString = descriptor.getFileNameItmes();
try {
JSONParser jsonParser = new JSONParser(-1);
JSONArray jsonArray = (JSONArray)jsonParser.parse(fileNameItmesJSONString);
if(descriptor.getFileNameSeperator().equals("byte")) {
//TODO
} else {
String[] fileNameSplit = noExtensionName.split(Matcher.quoteReplacement(descriptor.getFileNameSeperator()));
for(int i=0; i<jsonArray.size(); i++) {
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
String key = jsonObject.keySet().iterator().next();
if(fileNameSplit.length > i) {
dataObject.put(key, fileNameSplit[i]);
} else {
dataObject.put(key, "");
}
}
}
} catch (ParseException e) {
e.printStackTrace();
}
}
/** .<br />
* @param string , sep
* @return
*/
public String[] smartSplit(String string, String sep) {
if(sep.equals("LineBreak")) {
return string.split("\r?\n|\r");
} else {
return string.split(Matcher.quoteReplacement(sep));
}
}
}

@ -30,7 +30,7 @@ public class OnlyImageParser extends LayoutParser {
.collect(Collectors.toList());
sortedFileList.forEach(item -> {
DataObject dataObject = new DataObject();
DataObject dataObject = this.createParsedDataObject();
dataObject.put("FILE_GROUP_TYPE", "JPG");
File file = item.toFile();
@ -53,48 +53,31 @@ public class OnlyImageParser extends LayoutParser {
String noExtensionName = FilenameUtils.removeExtension(fileName);
this.analyzeFileName(dataObject, noExtensionName);
this.refineValue(dataObject);
String[] fileNameSplit = noExtensionName.split(Matcher.quoteReplacement(descriptor.getFileNameSeperator()));
dataObject.put("EQPMNT_CD", fileNameSplit[0]);
dataObject.put("CRDN_TIMESTAMP", fileNameSplit[1]);
dataObject.put("CRDN_YMD", fileNameSplit[1].substring(0,8));
dataObject.put("CRDN_TM", fileNameSplit[1].substring(8,14));
dataObject.put("VHRNO", fileNameSplit[2]);
dataObject.put("PHOTO_CNT", fileNameSplit[3]);
String photoType = fileNameSplit[4];
dataObject.put("PHOTO_TYPE", photoType);
String photoSeqNm = "";
if(photoType.equals("1")) photoSeqNm = "입차사진";
else if(photoType.equals("2")) photoSeqNm = "주차사진";
else if(photoType.equals("3")) photoSeqNm = "위반사진";
else if(photoType.equals("4")) photoSeqNm = "출차사진";
dataObject.put("PHOTO_TYPE_NM", photoSeqNm);
dataObject.put("PHOTO_TYPE_CD", fileNameSplit[4]);
dataObject.put("GPS_X", fileNameSplit[5]);
dataObject.put("GPS_Y", fileNameSplit[6]);
String inputSe = fileNameSplit[7];
if(inputSe.equals("S")) inputSe = "정상등록자료";
else if(inputSe.equals("E")) inputSe = "삭제자료";
dataObject.put("FILE_STATUS", inputSe);
dataObject.put("FILE_STATUS_CD", fileNameSplit[7]);
dataObject.put("CRDN_PLC", fileNameSplit[8]);
dataObject.put("CRDN_ADDRESS", fileNameSplit[9]);
dataObject.put("CRDN_ROAD_NM", fileNameSplit[9]);
dataObject.put("CRDN_STDG_NM", fileNameSplit[10]);
if(fileNameSplit.length >= 12) {
String crdnCn = fileNameSplit[11];
if(crdnCn.equals("00")) crdnCn = "사용안함";
else if(crdnCn.equals("01")) crdnCn = "일반차량(전기차)";
else if(crdnCn.equals("02")) crdnCn = "장기주차(전기차)";
dataObject.put("CRDN_CN", crdnCn);
dataObject.put("CRDN_CN_CD", crdnCn);
}
if(!before.isEmpty()) {
boolean isChangeTempGroup = this.isChangeCrackdown(dataObject, before);
if(isChangeTempGroup) {
@ -122,7 +105,7 @@ public class OnlyImageParser extends LayoutParser {
return true;
}
if(currentItem.number("PHOTO_TYPE").intValue() <= beforeItem.number("PHOTO_TYPE").intValue()) {
if(currentItem.number("PHOTO_TYPE_CD").intValue() <= beforeItem.number("PHOTO_TYPE_CD").intValue()) {
return true;
}

@ -29,7 +29,8 @@ public class SingleFileParser extends LayoutParser {
List<DataObject> dataObjectList = new ArrayList<>();
fileList.forEach(item -> {
DataObject dataObject = new DataObject();
DataObject dataObject = this.createParsedDataObject();
dataObject.put("FILE_GROUP_TYPE", "BIN");
File file = item.toFile();

@ -125,9 +125,9 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ
crdn.setGpsY(linkFileInfo.string("GPS_Y"));
crdn.setCrdnStdgNm(linkFileInfo.string("CRDN_STDG_NM"));
crdn.setCrdnPlc(linkFileInfo.string("CRDN_PLC"));
crdn.setCrdnRoadNm(linkFileInfo.string("CRDN_ROAD_NM"));
//linkFileInfo.string("EQPMNT_CD");
//linkFileInfo.string("CRDN_ADDRESS");
List<File> files = new ArrayList<>();
for (DataObject linkFileInfo0 : linkFileInfoList) {
@ -172,14 +172,14 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ
crdn.setCrdnEndTm(metaFileInfo.string("CRDN_END_TM"));
crdn.setCrdnPlc(metaFileInfo.string("CRDN_PLC"));
if(metaFileInfo.string("SPECIAL_AREA").equals("어린이보호구역")) {
if(metaFileInfo.string("CRDN_SPAREA_NM").equals("어린이보호구역")) {
crdn.setCrdnSpareaCd("01");
} else {
crdn.setCrdnSpareaCd("00");
}
crdn.setCrdnStdgNm(metaFileInfo.string("CRDN_STDG_NM"));
//metaFileInfo.string("LAW");
//metaFileInfo.string("VLTN_NM");
//metaFileInfo.string("EQPMNT_CD");
List<File> files = new ArrayList<>();

@ -242,6 +242,8 @@ public class Crdn05Controller extends ApplicationController {
String deptCd = currentUser.getDeptCode();
List<LayoutDescriptor> layoutDescriptors = crdnStngService.getLinkFileLayoutMetadata(sggCd, taskSeCd, institute, deptCd);
Map<String, List<CommonCode>> codeInfo = getCodesOf("FIM007","WEB002","FIM005","FIM006","FIM005","FIM061");
if(layoutDescriptors == null || layoutDescriptors.isEmpty()) {
throw new RuntimeException("연계파일 레이아웃 정보 조회에 실패하였습니다.");
}
@ -264,6 +266,7 @@ public class Crdn05Controller extends ApplicationController {
case "BIN": parser = new SingleFileParser(); break;
}
parser.addCommonCode(codeInfo);
parser.setDescriptor(layoutDescriptors.get(i));
if(!fileList.isEmpty()) {

@ -18,6 +18,7 @@
<result property="contentSeperator" column="DATA_SE_TYPE1" /> <!-- 자료 구분 유형1 -->
<result property="contentSecondSeperator" column="DATA_SE_TYPE2" /> <!-- 자료 구분 유형2 -->
<result property="secondSeperatorStarterItems" column="DATA_LAYOUT2" /> <!-- 자료 형식2 -->
<result property="enterpriseName" column="ENT_NM" /> <!-- 레이아웃 업체명 -->
<result property="linkEnterpriseName" column="LINK_ENT_NM" /> <!-- 연계 업체 명 -->
</resultMap>
@ -76,6 +77,7 @@ SELECT A.FILE_LAYOUT_ID
, A.DATA_LAYOUT2
, A.FILE_TNOCS
, A.LINK_FILE_PATH
, A.ENT_NM
, B.LINK_ENT_NM
FROM TB_CRDN_FILE_LAYOUT A
LEFT OUTER JOIN TB_FTP_INFO B ON (A.FILE_LAYOUT_ID = B.FILE_LAYOUT_ID)

@ -75,7 +75,7 @@
<th style="min-width: 80px;">차량번호</th>
<th style="min-width: 80px;">사진구분명</th>
<th style="min-width: 80px;">업체코드</th>
<th style="min-width: 80px;">법규</th>
<th style="min-width: 80px;">위반내용</th>
<th style="min-width: 80px;">차량속도</th>
<th style="min-width: 80px;">번호판위치x</th>
<th style="min-width: 80px;">번호판위치y</th>
@ -103,14 +103,14 @@
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{FILE_LAST_MODIFIED}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{FILE_SIZE}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{FILE_EXTENSION}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{FILE_STATUS}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{FILE_STATUS_NM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-end">{PHOTO_CNT}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{FILE_SEQ}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{EQPMNT_CD}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{VHRNO}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{PHOTO_TYPE_NM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{ENT_CD}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{LAW}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{BZENTY_CD}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{VLTN_NM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{CAR_VELOCITY}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-end">{MOSC_X}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-end">{MOSC_Y}</td>
@ -122,10 +122,10 @@
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{CRDN_TM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{CRDN_BGNG_TM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center">{CRDN_END_TM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{SPECIAL_AREA}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{CRDN_SPAREA_NM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{CRDN_PLC}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{CRDN_STDG_NM}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{CRDN_ADDRESS}</td>
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-start">{CRDN_ROAD_NM}</td>
</tr>
</template>
<template class="notFound">

Loading…
Cancel
Save