全是代码,整个逻辑都在里面,可贴纹理
/**
* geoJSON 生成dae 接口
* ...
*
* @author qzblm
*/
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jetbrains.annotations.NotNull;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.triangulate.DelaunayTriangulationBuilder;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.http.HttpServletResponse;
import java.awt.geom.Point2D;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ColladaExporter{
/**
* 导出obj格式。
*
* @param geoJSON 示例参数 {"features"}
* @return 示例返回值生成的obj的zip
*/
public static String LoadObj(String geoJSON ) throws IOException {
// String filePath = "E:\\tiff\\one.json";
char randomLetter = generateRandomLetter();
CreateDirPath("D:\\objs\\");
String createPath = "D:\\objs\\"+randomLetter+randomLetter+randomLetter;
CreateDirPath(createPath);
String objFilename = createPath+"\\models.dae";
CreateDir(objFilename);//创造文件obj
ObjectMapper objectMapper = new ObjectMapper();
JsonNode geoJson = objectMapper.readTree(geoJSON);
JsonNode features = geoJson.get("features");
List<String> objAll = new ArrayList<>();
List<String> objVT = new ArrayList<>();
List<String> objVn = new ArrayList<>();
List<String> mtl = new ArrayList<>();
String Collada ="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" +
"<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">\n";
String asset =" <asset>\n" +
" <contributor>\n" +
" <author>GDobj2Collada</author>\n" +
" <authoring_tool>GDobj2Collada Exporter</authoring_tool>\n" +
" </contributor>\n" +
" <created>2023-10-07T08:59:24</created>\n" +
" <modified>2023-10-07T08:59:24</modified>\n" +
" <unit name=\"meter\" meter=\"1\" />\n" +
" <up_axis>Y_UP</up_axis>\n" +
" </asset>\n";
String library_images ="<library_images>\n";
String library_effects = " <library_effects>\n" +
" <effect id=\"DefaultMaterial-fx\" name=\"DefaultMaterial\">\n" +
" <profile_COMMON>\n" +
" <technique sid=\"standard\">\n" +
" <phong>\n" +
" <emission>\n" +
" <color sid=\"emission\">0 0 0 1</color>\n" +
" </emission>\n" +
" <ambient>\n" +
" <color sid=\"ambient\">0 0 0 1</color>\n" +
" </ambient>\n" +
" <diffuse>\n" +
" <color sid=\"diffuse\">0.60000002 0.60000002 0.60000002 1</color>\n" +
" </diffuse>\n" +
" <specular>\n" +
" <color sid=\"specular\">0 0 0 1</color>\n" +
" </specular>\n" +
" <shininess>\n" +
" <float sid=\"shininess\">0</float>\n" +
" </shininess>\n" +
" <transparent>\n" +
" <color sid=\"transparent\">1 1 1 1</color>\n" +
" </transparent>\n" +
" <transparency>\n" +
" <float sid=\"transparency\">1</float>\n" +
" </transparency>\n" +
" <index_of_refraction>\n" +
" <float sid=\"index_of_refraction\">1</float>\n" +
" </index_of_refraction>\n" +
" </phong>\n" +
" </technique>\n" +
" </profile_COMMON>\n" +
" </effect>\n";
String library_materials = " <library_materials>\n" +
" <material id=\"DefaultMaterial\" name=\"DefaultMaterial\">\n" +
" <instance_effect url=\"#DefaultMaterial-fx\"/>\n" +
" </material>\n";
String library_geometries = " <library_geometries>\n";
String library_visual_scenes =" <library_visual_scenes>\n" +
" <visual_scene id=\"models.obj\" name=\"models.obj\">\n";
int objVTs = 0;
int f = 1;
int index = 1;
for(int i =0;i<features.size();i++){
List<String> objV = new ArrayList<>();
List<String> objF = new ArrayList<>();
JsonNode properties = features.get(i).get("properties");
String Z = "0.0";
System.out.println("生成中"+features.get(i).get("id"));
String ZH = properties.get("height").toString();
ZH = ZH.substring(1, ZH.length() - 1);
String floor = properties.get("floor").toString();
floor = floor.substring(1, floor.length() - 1);
double floors = Double.parseDouble(floor);
// JsonNode h2 = objectMapper.readTree(h3.toString().replaceAll("\"", ""));
// JsonNode data2 =features.get(0).get("properties").get("outloop")
JsonNode data2 = objectMapper.readTree(properties.get("outloop").toString().replaceAll("\"", ""));
JsonNode url = properties.get("url");
for(int a =0;a< url.size();a++){
if(url.get(a).toString().length()>2){
loadTextrue(url.get(a).toString(),createPath+"\\texture"+(i+a)+".png");
mtl.add("newmtl material"+(i+a)+"\n");
mtl.add("Ns 250.000000\n");
mtl.add("Ka 1.000000 1.000000 1.000000\n");
mtl.add("Ks 0.500000 0.500000 0.500000\n");
mtl.add("Ke 0.000000 0.000000 0.000000\n");
mtl.add("Ni 1.450000\n");
mtl.add("d 1.000000\n");
mtl.add("illum 2\n");
mtl.add("map_Kd "+"texture"+(i+a)+".png\n");
library_images += "<image id=\"material"+(i+a)+"-diffuse-image\">\n" +
" <init_from>texture"+i+".png</init_from>\n" +
" </image>\n";
}
}
library_effects +=" <effect id=\"material"+i+"-fx\" name=\"material"+i+"\">\n" +
" <profile_COMMON>\n" +
" <newparam sid=\"material"+i+"-diffuse-surface\">\n" +
" <surface type=\"2D\">\n" +
" <init_from>material"+i+"-diffuse-image</init_from>\n" +
" </surface>\n" +
" </newparam>\n" +
" <newparam sid=\"material"+i+"-diffuse-sampler\">\n" +
" <sampler2D>\n" +
" <source>material"+i+"-diffuse-surface</source>\n" +
" </sampler2D>\n" +
" </newparam>\n" +
" <technique sid=\"standard\">\n" +
" <phong>\n" +
" <emission>\n" +
" <color sid=\"emission\">0 0 0 1</color>\n" +
" </emission>\n" +
" <ambient>\n" +
" <color sid=\"ambient\">1 1 1 1</color>\n" +
" </ambient>\n" +
" <diffuse>\n" +
" <texture texture=\"material"+i+"-diffuse-sampler\" texcoord=\"CHANNEL0\" />\n" +
" </diffuse>\n" +
" <specular>\n" +
" <color sid=\"specular\">0.5 0.5 0.5 1</color>\n" +
" </specular>\n" +
" <shininess>\n" +
" <float sid=\"shininess\">250</float>\n" +
" </shininess>\n" +
" <transparent>\n" +
" <color sid=\"transparent\">1 1 1 1</color>\n" +
" </transparent>\n" +
" <transparency>\n" +
" <float sid=\"transparency\">1</float>\n" +
" </transparency>\n" +
" <index_of_refraction>\n" +
" <float sid=\"index_of_refraction\">1.45</float>\n" +
" </index_of_refraction>\n" +
" </phong>\n" +
" </technique>\n" +
" </profile_COMMON>\n" +
" </effect>\n";
library_materials += " <material id=\"material"+i+"\" name=\"material"+i+"\">\n" +
" <instance_effect url=\"#material"+i+"-fx\"/>\n" +
" </material>\n";
List<Double[]> point = new ArrayList<>();
for(int z =0;z<data2.size();z++){
JsonNode data5 = data2.get(z);
if(data5 != null){
Double[] data3 ={
data5.get(0).asDouble(),data5.get(1).asDouble()};
String Z1 = "50.0";
data3[1] = (data3[1]);
data3[0] = (data3[0]);
point.add(data3);
}
}
// 计算面周长
Double perimeter = (double) 0;
List<Double> perimeters = new ArrayList<>();
for(int z = 0;z+1<point.size();z++){
Double[] Around1 = point.get(z);
Double[] Around2 = point.get(z+1);
Point2D.Double p1 = new Point2D.Double( Around1[0], Around1[1]);
Point2D.Double p2 = new Point2D.Double(Around2[0], Around2[1]);
double distance = p1.distance(p2);
perimeter += distance;
perimeters.add(distance);
}
Double perimeter2 = (double) 0;
// point.add(point.get(0));
// 生成周边
for(int z = 0;z+1<point.size();z++){
Double[] Around1 = point.get(z);
Double[] Around2 = point.get(z+1);
perimeter2 += perimeters.get(z);
objVn.add("vn -0.0000 -0.0000 -1.0000\n");
objVT.add(((perimeter2-perimeters.get(z))/perimeter)+" 0.0");
objVT.add(perimeter2/perimeter+" 0.0 ");
objVT.add(perimeter2/perimeter+" 1.0 ");
objVT.add(((perimeter2-perimeters.get(z))/perimeter)+" 1.0 ");
String F1 = objV.size() + " " + (objV.size() + 1)+ " " + (objV.size() + 2)+ " " ;
F1 += objV.size() + " " + (objV.size() + 2)+ " " + (objV.size() + 3);
String V1 = Around1[0] + " " + Z + " " + Around1[1] + " ";
String V2 = Around2[0] + " " + Z + " " + Around2[1] + " ";
String V3 = Around2[0] + " " + ZH + " " + Around2[1] + " ";
String V4 = Around1[0] + " " + ZH + " " + Around1[1] + " ";
f +=1;
objV.add(V1);objV.add(V2);objV.add(V3);objV.add(V4);
objF.add(F1);
}
point.add(point.get(0));
List<Coordinate> coordinateList = new ArrayList<>();
for (int c =0;c<point.size();c++){
coordinateList.add(new Coordinate(point.get(c)[0],point.get(c)[1],0));
}
Coordinate[] coords = coordinateList.toArray(new Coordinate[0]);
GeometryFactory geomFactory = new GeometryFactory();
LinearRing shell = geomFactory.createLinearRing(coords);
Polygon polygon = geomFactory.createPolygon(shell, null);
DelaunayTriangulationBuilder builders = new DelaunayTriangulationBuilder();
builders.setSites(polygon);
GeometryCollection triangles = (GeometryCollection) builders.getTriangles(geomFactory);
// int bc = objV.size();
for (int c = 0; c < triangles.getNumGeometries(); c++) {
Polygon triangle = (Polygon) triangles.getGeometryN(c);
boolean isInnerPolygonContained = polygon.intersects(triangle)&& !polygon.touches(triangle);
if(isInnerPolygonContained){
//生成顶部
objVT.add("0.0 0.0 ");
objVT.add("1.0 0.0 ");
objVT.add("1.0 1.0 ");
String F1 = objV.size() + " " + (objV.size()+1) + " " + (objV.size()+2) + " ";
objVn.add("vn -0.0000 -0.0000 -1.0000\n");
String V1 = triangle.getCoordinates()[0].x + " 0 " + triangle.getCoordinates()[0].y + " ";
String V2 = triangle.getCoordinates()[1].x + " 0 " + triangle.getCoordinates()[1].y + " ";
String V3 = triangle.getCoordinates()[2].x + " 0 " + triangle.getCoordinates()[2].y + " ";
objV.add(V1);objV.add(V2);objV.add(V3);
objF.add(F1);
f +=1;
//生成底部
objVT.add("0.0 0.0 ");
objVT.add("1.0 0.0 ");
objVT.add("1.0 1.0 ");
String F2 = objV.size() + " " + (objV.size()+1) + " " + (objV.size()+2) + " ";
V1 = triangle.getCoordinates()[0].x + " " + ZH + " " + triangle.getCoordinates()[0].y + " ";
V2 = triangle.getCoordinates()[1].x + " " + ZH + " " + triangle.getCoordinates()[1].y + " ";
V3 = triangle.getCoordinates()[2].x + " " + ZH + " " + triangle.getCoordinates()[2].y + " ";
objV.add(V1);objV.add(V2);objV.add(V3);
objF.add(F2);
f +=1;
}
}
objAll.add("o Cylinder_"+index+"\n");
index+=1;
String positions_array = "";
String tex_array ="";
String p = "";
String vcount = "";
String normals_array ="";
for(int b =0;b<objV.size();b++){
positions_array +=objV.get(b) ;
normals_array +="-0 -0 -1 ";
}
for(int b =0;b<objVT.size();b++){
tex_array += objVT.get(b)+" ";
}
for(int b =0;b<objF.size();b++){
p += objF.get(b)+" ";
if(objF.get(b).split(" ").length==6){
vcount += "3 3 ";
}else{
vcount += "3 ";
}
}
objVTs+=objV.size();
library_geometries +=" <geometry id=\"meshId"+i+"\" name=\"meshId"+i+"_name\" >\n" +
" <mesh>\n" +
" <source id=\"meshId"+i+"-positions\" name=\"meshId"+i+"-positions\">\n" +
" <float_array id=\"meshId"+i+"-positions-array\" count=\""+objV.size()*3+"\">" +
positions_array +
" </float_array>\n" +
" <technique_common>\n" +
" <accessor count=\""+objV.size()+"\" offset=\"0\" source=\"#meshId"+i+"-positions-array\" stride=\"3\">\n" +
" <param name=\"X\" type=\"float\" />\n" +
" <param name=\"Y\" type=\"float\" />\n" +
" <param name=\"Z\" type=\"float\" />\n" +
" </accessor>\n" +
" </technique_common>\n" +
" </source>\n";
library_geometries += " <source id=\"meshId"+i+"-normals\" name=\"meshId"+i+"-normals\">\n" +
" <float_array id=\"meshId"+i+"-normals-array\" count=\""+objV.size()*3+"\">\n" +
normals_array +
" </float_array>\n" +
" <technique_common>\n" +
" <accessor count=\"2250\" offset=\"0\" source=\"#meshId"+i+"-normals-array\" stride=\"3\">\n" +
" <param name=\"X\" type=\"float\" />\n" +
" <param name=\"Y\" type=\"float\" />\n" +
" <param name=\"Z\" type=\"float\" />\n" +
" </accessor>\n" +
" </technique_common>\n" +
" </source>\n";
library_geometries += "<source id=\"meshId"+i+"-tex0\" name=\"meshId"+i+"-tex0\">\n" +
" <float_array id=\"meshId"+i+"-tex0-array\" count=\""+objV.size()*2+"\">" +
tex_array+
"</float_array>\n" +
" <technique_common>\n" +
" <accessor count=\""+objV.size()+"\" offset=\"0\" source=\"#meshId"+i+"-tex0-array\" stride=\"2\">\n" +
" <param name=\"S\" type=\"float\" />\n" +
" <param name=\"T\" type=\"float\" />\n" +
" </accessor>\n" +
" </technique_common>\n" +
" </source>\n";
library_geometries += " <vertices id=\"meshId"+i+"-vertices\">\n" +
" <input semantic=\"POSITION\" source=\"#meshId"+i+"-positions\" />\n" +
" </vertices>\n";
library_geometries += "<polylist count=\"900\" material=\"defaultMaterial\">\n" +
" <input offset=\"0\" semantic=\"VERTEX\" source=\"#meshId"+i+"-vertices\" />\n" +
" <input offset=\"0\" semantic=\"NORMAL\" source=\"#meshId"+i+"-normals\" />\n" +
" <input offset=\"0\" semantic=\"TEXCOORD\" source=\"#meshId"+i+"-tex0\" set=\"0\" />\n" +
" <vcount>" +
vcount+
"</vcount>\n" +
" <p>" +
p+
"</p>\n" +
" </polylist>\n" +
" </mesh>\n" +
" </geometry>\n";
library_visual_scenes+=
" <node id=\"Cylinder_"+(i+1)+"\" name=\"Cylinder_"+(i+1)+"\" type=\"NODE\">\n" +
" <matrix sid=\"matrix\">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>\n" +
" <instance_geometry url=\"#meshId"+i+"\">\n" +
" <bind_material>\n" +
" <technique_common>\n" +
" <instance_material symbol=\"defaultMaterial\" target=\"#material"+i+"\">\n" +
" <bind_vertex_input semantic=\"CHANNEL0\" input_semantic=\"TEXCOORD\" input_set=\"0\"/>\n" +
" </instance_material>\n" +
" </technique_common>\n" +
" </bind_material>\n" +
" </instance_geometry>\n" +
" </node>\n";
}
library_images += " </library_images>\n";
library_effects += " </library_effects>\n";
library_materials += " </library_materials>\n";
library_geometries += " </library_geometries>\n";
library_visual_scenes +=" </visual_scene>\n" +
" </library_visual_scenes>\n";
Collada += asset +
library_images +
library_effects+
library_effects+
library_materials+library_geometries+
" <library_controllers>\n" +
" </library_controllers>\n"+
library_visual_scenes+" " +
" <scene>\n" +
" <instance_visual_scene url=\"#models.obj\" />\n" +
" </scene>\n" +
"</COLLADA>";
CreateObj(objFilename,Collada);
createZip(createPath+"\\archive.zip",createPath);
return createPath;
}
/**
* 得到最大最小值。
*
* @param features 示例参数 {"features"}
* @return MaxMin
*/
private static Double[] getMaxMin(JsonNode features){
Double[] MaxMin = new Double[2];
MaxMin[0] = -100000000000000.0;
MaxMin[1] = -100000000000000.0;
for(int i =0;i<features.size();i++) {
JsonNode data1 = features.get(i).get("geometry");
JsonNode data2 = data1.get("coordinates");
for (int z = 0; z < data2.size(); z++) {
JsonNode data5 = data2.get(z);
System.out.println(data5.size());
if (data5.size() == 2) {
// Double[] data3 = CoordinateConverter(data5.get(0), data5.get(1));
Double[] data3 ={
data5.get(0).asDouble(),data5.get(1).asDouble()};
if (MaxMin[0] < data3[0]) {
MaxMin[0] = data3[0];
}
if (MaxMin[1] < data3[1]) {
MaxMin[1] = data3[1];
}
}
}
}
return MaxMin;
}
/**
* 创造obj文件。
*
* @param objFilename 示例参数 {"features"}
* @param mtlFilename 示例参数 {"features"}
* @param mtl 示例参数 {"features"}
* @param objAll 示例参数 {"features"}
* @return MaxMin
*/
private static void CreateObj(
String objFilename,
String mtlFilename
) throws IOException{
FileWriter mtlWriter = new FileWriter(objFilename);
mtlWriter.write(mtlFilename);
mtlWriter.close();
System.out.println("Dae模型文件已生成。");
}
/**
* 创造压缩文件。
*
* @param zipFile 示例参数 {"features"}
* @param sourceFolder 示例参数 {"features"}
* @return MaxMin
*/
private static void createZip(String zipFile,String sourceFolder) throws IOException {
File file = new File(sourceFolder);
file.createNewFile();
// 创建输出压缩文件流
try (FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos)) {
// 压缩文件夹及其内容
compressFolder(new File(sourceFolder), zos, "",zipFile);
System.out.println("文件夹及其内容已成功压缩为:" + zipFile);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创造压缩文件。
*
* @param folder 示例参数 {"features"}
* @param zos 示例参数 {"features"}
* @param parentPath 示例参数 {"features"}
* @param excludeFile 示例参数 {"features"}
* @return MaxMin
*/
private static void compressFolder(File folder, ZipOutputStream zos, String parentPath, String excludeFile) throws IOException {
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
// 递归压缩子目录
compressFolder(file, zos, parentPath + file.getName() + "/", excludeFile);
} else {
// 排除zip文件
if (!file.getAbsolutePath().equals(excludeFile) && !isZipFile(file)) {
// 压缩文件
String entryPath = parentPath + file.getName();
zos.putNextEntry(new ZipEntry(entryPath));
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
}
zos.closeEntry();
}
}
}
}
/**
* 排除压缩文件。
*
* @param file 示例参数 {"features"}
* @return MaxMin
*/
private static boolean isZipFile(File file) {
String fileName = file.getName();
return fileName.endsWith(".zip") || fileName.endsWith(".ZIP");
}
//添加压缩包
private static void addToZip(File file, ZipOutputStream zos, String parentFolder) throws IOException {
FileInputStream fis = new FileInputStream(file);
// 获取文件相对于父文件夹的路径
String entryPath = parentFolder + file.getName();
// 创建ZipEntry对象并设置名称
ZipEntry entry = new ZipEntry(entryPath);
// 将ZipEntry对象添加到ZipOutputStream中
zos.putNextEntry(entry);
// 从输入流中读取数据并写入压缩文件中
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) >= 0) {
zos.write(buffer, 0, length);
}
// 关闭当前条目并将流定位到下一个条目的开头
zos.closeEntry();
fis.close();
}
public static char generateRandomLetter() {
Random random = new Random();
int randomNumber = random.nextInt(26); // 生成一个0到25之间的随机数
char randomLetter = (char) (randomNumber + 'A'); // 将随机数转换为对应的大写字母
return randomLetter;
}
private static Double[] CoordinateConverter(JsonNode longitude,JsonNode latitude){
double lonRad = Math.toRadians(longitude.asDouble());
double latRad = Math.toRadians(latitude.asDouble());
// 椭球体参数
double a = 6378137; // 长半轴
double e = 0.081819190842621; // 第一偏心率的平方根
// 计算转换后的坐标
double x = a * lonRad;
double y = a * Math.log(Math.tan(Math.PI / 4 + latRad / 2) * Math.pow((1 - e * Math.sin(latRad)) / (1 + e * Math.sin(latRad)), e / 2));
Double[] data =new Double[2];
data[0] = x;
data[1] = y;
return data;
}
private static void CreateDirPath(String folderPath)throws IOException{
File folder = new File(folderPath);
if (folder.mkdir()) {
// System.out.println("Folder created successfully.");
} else {
// System.out.println("Failed to create folder.");
}
}
//创建文件
private static void CreateDir(String objFilename) throws IOException {
File file = new File(objFilename);
if (file.createNewFile()) {
} else {
}
}
//导出纹理
private static void loadTextrue(String base64String,String outputPath) throws IOException {
String modifiedStr = base64String.substring(1, base64String.length() - 1);
String[] a= modifiedStr.split(",");
byte[] imageBytes = Base64.getDecoder().decode(a[1]);
// 创建输出流
OutputStream outputStream = new FileOutputStream(outputPath);
// 将字节数组写入输出流
outputStream.write(imageBytes);
// 关闭输出流
outputStream.close();
}
@PostMapping("/getGeojson")
@CrossOrigin(origins = "*")
public ResponseEntity<byte[]> downloadFile(@RequestBody String geojson, HttpServletResponse response) throws IOException {
ObjModelGenerator objModelGenerator = new ObjModelGenerator();
String filePath = LoadObj(geojson);
String zip = filePath+"\\archive.zip";
byte[] fileBytes = getFileBytes(zip);
// 设置响应头部信息
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", "archive.zip");
deleteFolder(new File(filePath));
return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
}
//得到压缩包文件流
private byte[] getFileBytes(String filePath) throws IOException {
File file = new File(filePath);
byte[] fileBytes = new byte[(int) file.length()];
try (FileInputStream fis = new FileInputStream(file)) {
fis.read(fileBytes);
}
return fileBytes;
}
//删除生成的文件
private static void deleteFolder(File folder) {
if (folder.isDirectory()) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
deleteFolder(file);
}
}
}
// 删除文件或空目录
folder.delete();
}
}
文章浏览阅读86次。首发地址:https://yq.aliyun.com/articles/221708谈到机器学习,相信很多除学者都是通过斯坦福大学吴恩达老师的公开课《Machine Learning》开始具体的接触机器学习这个领域,但是学完之后又不知道自己的掌握情况,缺少一些实际的项目操作。对于机器学习的相关竞赛挑战,有些项目的门槛有些高,参加后难以具体的实现,因此造..._scrath五子棋下载
文章浏览阅读83次。原标题:Oracle 12c新特性系列专题-安徽Oracle授权认证中心 随着Oracle database 12c的普及,数据库管理员 (DBA) 的角色也随之发生了转变。 Oracle 12c数据库对 DBA 而言是下一代数据管理。它让 DBA 可以摆脱单调的日常管理任务,能够专注于如何从数据中获取更多价值。未来我们会推出基于Oracle12c的技术文章,帮助DBA尽快掌握新一代数据库的新特性..._ilm add policy row store compress advanced row after
文章浏览阅读150次。问题及代码:*Copyright(c)2016,烟台大学计算机与控制工程学院 *All right reserved. *文件名称:负数把正数赶出队列.cpp *作者:张冰 *完成日期;2016年10月09日 *版本号;v1.0 * *问题描述: 设从键盘输入一整数序列a1,a2,…an,试编程实现: 当ai>0时,ai进队,当ai<0时,将队首元素出队,当ai
文章浏览阅读376次。贪心+构造
文章浏览阅读150次。本文讲的是Linux命名空间学习教程(二) IPC,【编者的话】Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。而 LXC所实现的隔离性主要是来自内核的命名空间, 其中pid、net、ipc、mnt、uts 等命名空间将容器的进程、网络、消息、文件系统和hostname 隔离开。本文是Li..._主机的 ipc 命名空间
文章浏览阅读2w次,点赞5次,收藏7次。在设备上强制安装apk。在app已有的情况下使用-r参数在app版本低于现有版本使用-d参数命令adb install -r -d xxx.apk_adb绕过安装程序强制安装app
文章浏览阅读290次。如果是越界进入硬件错误中断,MSP 或者 PSP 保存错误地址,跳转前会保存上一次执行的地址,lr 寄存器会保存子函数的地址,所以如果在 HardFault_CallBack 中直接调用 C 语言函数接口会间接修改了 lr,为了解决这个问题,直接绕过 lr 的 C 语言代码,用汇编语言提取 lr 寄存器再决定后面的操作。由于 STM32 加入了 FreeRTOS 操作系统,可能导致无法准确定位,仅供参考(日常编程需要考虑程序的健壮性,特别是对数组的访问,非常容易出现越界的情况)。_stm32flash地址越界怎么解决
文章浏览阅读1.8k次。学到了一种操作,说实话,我从来没想过还能这样正常情况下,为了管理方便,许多管理员都会开放MySQL数据库的secure_file_priv,这时就可以导入或者导出数据当我如图输入时,就会在D盘创建一个名为123456.php,内容为<?php phpinfo();?>的文件我们可以利用这一点运用到SQL注入中,从拿下数据库到拿下目标的服务器比如我们在使用联合查询注入,正常是这样的语句http://xxx?id=-1 union select 1,'你想知道的字段的内容或查询语句',
文章浏览阅读2.9w次,点赞12次,收藏63次。感谢原文:https://blog.csdn.net/abc5382334/article/details/24260817感谢原文:https://blog.csdn.net/jiaqingge/article/details/52564348Html CSS的三种链接方式css文本的链接方式有三种:分别是内联定义、链入内部css、和链入外部css1.代码为:<html>..._html链接css代码
文章浏览阅读625次。近几年,蓝牙耳机市场发展迅速,越来越多的消费者希望抛弃线缆,更自由地听音乐,对于运动人士来说,蓝牙耳机的便携性显得尤为重要。但目前市面上的大多数蓝牙耳机实际上都是“有线”的,运动过程中产生的听诊器效应会严重影响听歌的感受。而在“真无线”耳机领域,除了苹果的AirPods外,可供选择的产品并不多,而AirPods又不是为运动场景打造的,防水能力非常差。那么对于喜欢运动又想要“自由”的朋友来说,有没有一款产品能够满足他们的需求呢?下面这十款小编专门为大家搜罗的蓝牙耳机或许就能找到适合的!网红击音F1_适合游戏与运动的高音质蓝牙耳机
文章浏览阅读1k次,点赞6次,收藏7次。在本篇博文中,我们在 iOS 17 beta 4(SwiftUI 5.0)测试版中发现了 SwiftUI 视图首次显示时状态的改变会导致动画“副作用”的问题,并提出多种解决方案。
文章浏览阅读1.9k次。 在 上篇文章–Flutter 实现支持上拉加载和下拉刷新的 ListView 中,我们最终实现的效果是在 listView 上面留下了一段空白,本意是用来加载轮播图的,于是今天就开发了一下,希望能给各位灵感。一 、效果如下说一下大体思路 其实图片展示是用的 PageView ,然后,下面的指示器 是用的 TabPageSelector ,当然整体是用 Stack 包裹起来的。1、..._flutter pageview轮播图 site:csdn.net